Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/User/Info.vue
<template> | <template> | ||||
<div class="container"> | <div class="container"> | ||||
<status-component v-if="user_id !== 'new'" :status="status" @status-update="statusUpdate"></status-component> | <status-component | ||||
v-if="user_id !== 'new'" | |||||
:status="status" | |||||
@status-update="statusUpdate" | |||||
></status-component> | |||||
<div class="card" id="user-info"> | <div class="card" id="user-info"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<div class="card-title" v-if="user_id !== 'new'">User account</div> | <div class="card-title" v-if="user_id !== 'new'"> | ||||
User account - | |||||
<small :class="$root.userStatusClass(user)" id="status">{{ | |||||
$root.userStatusText(user) | |||||
}}</small> | |||||
</div> | |||||
<div class="card-title" v-if="user_id === 'new'">New user account</div> | <div class="card-title" v-if="user_id === 'new'">New user account</div> | ||||
<div class="card-text"> | <div class="card-text"> | ||||
<ul class="nav nav-tabs mb-4" v-if="user_id !== 'new'"> | |||||
<li class="nav-item" v-on:click="tab = 'general'"> | |||||
<a class="nav-link active">General</a> | |||||
</li> | |||||
<li class="nav-item" v-on:click="tab = 'subscriptions'"> | |||||
<a class="nav-link">Subscriptions</a> | |||||
</li> | |||||
<li class="nav-item" v-on:click="tab = 'advanced'"> | |||||
<a class="nav-link">Advanced</a> | |||||
</li> | |||||
</ul> | |||||
<div class="container"> | |||||
<form @submit.prevent="submit"> | <form @submit.prevent="submit"> | ||||
<div v-if="user_id !== 'new'" class="form-group row plaintext"> | <div v-if="user_id == 'new' || tab == 'general'"> | ||||
<label for="first_name" class="col-sm-4 col-form-label">Status</label> | |||||
<div class="col-sm-8"> | |||||
<span :class="$root.userStatusClass(user) + ' form-control-plaintext'" id="status">{{ $root.userStatusText(user) }}</span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="first_name" class="col-sm-4 col-form-label">First name</label> | <label for="email" class="col-sm-4 col-form-label" | ||||
>Email</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<input type="text" class="form-control" id="first_name" v-model="user.first_name"> | <input | ||||
type="text" | |||||
class="form-control" | |||||
id="email" | |||||
:disabled="user_id !== 'new'" | |||||
required | |||||
v-model="user.email" | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="last_name" class="col-sm-4 col-form-label">Last name</label> | <label for="first_name" class="col-sm-4 col-form-label" | ||||
>First name</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<input type="text" class="form-control" id="last_name" v-model="user.last_name"> | <input | ||||
type="text" | |||||
class="form-control" | |||||
id="first_name" | |||||
v-model="user.first_name" | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="organization" class="col-sm-4 col-form-label">Organization</label> | <label for="last_name" class="col-sm-4 col-form-label" | ||||
>Last name</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<input type="text" class="form-control" id="organization" v-model="user.organization"> | <input | ||||
type="text" | |||||
class="form-control" | |||||
id="last_name" | |||||
v-model="user.last_name" | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="email" class="col-sm-4 col-form-label">Email</label> | <label for="organization" class="col-sm-4 col-form-label" | ||||
>Organization</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<input type="text" class="form-control" id="email" :disabled="user_id !== 'new'" required v-model="user.email"> | <input | ||||
type="text" | |||||
class="form-control" | |||||
id="organization" | |||||
v-model="user.organization" | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="aliases-input" class="col-sm-4 col-form-label">Email aliases</label> | <label for="aliases-input" class="col-sm-4 col-form-label" | ||||
>Email aliases</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<list-input id="aliases" :list="user.aliases"></list-input> | <list-input id="aliases" :list="user.aliases"></list-input> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="password" class="col-sm-4 col-form-label">Password</label> | <label for="password" class="col-sm-4 col-form-label" | ||||
>Password</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<input type="password" class="form-control" id="password" v-model="user.password" :required="user_id === 'new'"> | <input | ||||
type="password" | |||||
class="form-control" | |||||
id="password" | |||||
v-model="user.password" | |||||
:required="user_id === 'new'" | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="password_confirmaton" class="col-sm-4 col-form-label">Confirm password</label> | <label | ||||
for="password_confirmaton" | |||||
class="col-sm-4 col-form-label" | |||||
>Confirm password</label | |||||
> | |||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<input type="password" class="form-control" id="password_confirmation" v-model="user.password_confirmation" :required="user_id === 'new'"> | <input | ||||
type="password" | |||||
class="form-control" | |||||
id="password_confirmation" | |||||
v-model="user.password_confirmation" | |||||
:required="user_id === 'new'" | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div v-if="user_id === 'new'" id="user-packages" class="form-group row"> | <div | ||||
v-if="user_id === 'new'" | |||||
id="user-packages" | |||||
class="form-group row" | |||||
> | |||||
<label class="col-sm-4 col-form-label">Package</label> | <label class="col-sm-4 col-form-label">Package</label> | ||||
<div class="col-sm-8"> | <div class="col-sm-8"> | ||||
<table class="table table-sm form-list"> | <table class="table table-sm form-list"> | ||||
<thead class="thead-light sr-only"> | <thead class="thead-light sr-only"> | ||||
<tr> | <tr> | ||||
<th scope="col"></th> | <th scope="col"></th> | ||||
<th scope="col">Package</th> | <th scope="col">Package</th> | ||||
<th scope="col">Price</th> | <th scope="col">Price</th> | ||||
<th scope="col"></th> | <th scope="col"></th> | ||||
</tr> | </tr> | ||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<tr v-for="pkg in packages" :id="'p' + pkg.id" :key="pkg.id"> | <tr | ||||
v-for="pkg in packages" | |||||
:id="'p' + pkg.id" | |||||
:key="pkg.id" | |||||
> | |||||
<td class="selection"> | <td class="selection"> | ||||
<input type="checkbox" @click="selectPackage" | <input | ||||
type="checkbox" | |||||
@click="selectPackage" | |||||
:value="pkg.id" | :value="pkg.id" | ||||
:checked="pkg.id == package_id" | :checked="pkg.id == package_id" | ||||
:id="'pkg-input-' + pkg.id" | :id="'pkg-input-' + pkg.id" | ||||
> | /> | ||||
</td> | </td> | ||||
<td class="name"> | <td class="name"> | ||||
<label :for="'pkg-input-' + pkg.id">{{ pkg.name }}</label> | <label :for="'pkg-input-' + pkg.id">{{ | ||||
pkg.name | |||||
}}</label> | |||||
</td> | </td> | ||||
<td class="price text-nowrap"> | <td class="price text-nowrap"> | ||||
{{ $root.priceLabel(pkg.cost, 1, discount) }} | {{ $root.priceLabel(pkg.cost, 1, discount) }} | ||||
</td> | </td> | ||||
<td class="buttons"> | <td class="buttons"> | ||||
<button v-if="pkg.description" type="button" class="btn btn-link btn-lg p-0" v-tooltip.click="pkg.description"> | <button | ||||
v-if="pkg.description" | |||||
type="button" | |||||
class="btn btn-link btn-lg p-0" | |||||
v-tooltip.click="pkg.description" | |||||
> | |||||
<svg-icon icon="info-circle"></svg-icon> | <svg-icon icon="info-circle"></svg-icon> | ||||
<span class="sr-only">More information</span> | <span class="sr-only">More information</span> | ||||
</button> | </button> | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
</tbody> | </tbody> | ||||
</table> | </table> | ||||
<small v-if="discount > 0" class="hint"> | <small v-if="discount > 0" class="hint"> | ||||
<hr class="m-0"> | <hr class="m-0" /> | ||||
¹ applied discount: {{ discount }}% - {{ discount_description }} | ¹ applied discount: {{ discount }}% - | ||||
{{ discount_description }} | |||||
</small> | </small> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div v-if="user_id !== 'new'" id="user-skus" class="form-group row"> | </div> | ||||
<label class="col-sm-4 col-form-label">Subscriptions</label> | <div | ||||
<div class="col-sm-8"> | v-if="tab == 'subscriptions'" | ||||
id="user-skus" | |||||
class="form-group row" | |||||
> | |||||
<div class="col-sm-10"> | |||||
<table class="table table-sm form-list"> | <table class="table table-sm form-list"> | ||||
<thead class="thead-light sr-only"> | <thead class="thead-light sr-only"> | ||||
<tr> | <tr> | ||||
<th scope="col"></th> | <th scope="col"></th> | ||||
<th scope="col">Subscription</th> | <th scope="col">Subscription</th> | ||||
<th scope="col">Price</th> | <th scope="col">Price</th> | ||||
<th scope="col"></th> | <th scope="col"></th> | ||||
</tr> | </tr> | ||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<tr v-for="sku in skus" :id="'s' + sku.id" :key="sku.id"> | <tr v-for="sku in skus" :id="'s' + sku.id" :key="sku.id"> | ||||
<td class="selection"> | <td class="selection"> | ||||
<input type="checkbox" @input="onInputSku" | <input | ||||
type="checkbox" | |||||
@input="onInputSku" | |||||
:value="sku.id" | :value="sku.id" | ||||
:disabled="sku.readonly" | :disabled="sku.readonly" | ||||
:checked="sku.enabled" | :checked="sku.enabled" | ||||
:id="'sku-input-' + sku.title" | :id="'sku-input-' + sku.title" | ||||
> | /> | ||||
</td> | </td> | ||||
<td class="name"> | <td class="name"> | ||||
<label :for="'sku-input-' + sku.title">{{ sku.name }}</label> | <label :for="'sku-input-' + sku.title">{{ | ||||
sku.name | |||||
}}</label> | |||||
<div v-if="sku.range" class="range-input"> | <div v-if="sku.range" class="range-input"> | ||||
<label class="text-nowrap">{{ sku.range.min }} {{ sku.range.unit }}</label> | <label class="text-nowrap" | ||||
>{{ sku.range.min }} {{ sku.range.unit }}</label | |||||
> | |||||
<input | <input | ||||
type="range" class="custom-range" @input="rangeUpdate" | type="range" | ||||
class="custom-range" | |||||
@input="rangeUpdate" | |||||
:value="sku.value || sku.range.min" | :value="sku.value || sku.range.min" | ||||
:min="sku.range.min" | :min="sku.range.min" | ||||
:max="sku.range.max" | :max="sku.range.max" | ||||
> | /> | ||||
</div> | </div> | ||||
</td> | </td> | ||||
<td class="price text-nowrap"> | <td class="price text-nowrap"> | ||||
{{ $root.priceLabel(sku.cost, 1, discount) }} | {{ $root.priceLabel(sku.cost, 1, discount) }} | ||||
</td> | </td> | ||||
<td class="buttons"> | <td class="buttons"> | ||||
<button v-if="sku.description" type="button" class="btn btn-link btn-lg p-0" v-tooltip.click="sku.description"> | <button | ||||
v-if="sku.description" | |||||
type="button" | |||||
class="btn btn-link btn-lg p-0" | |||||
v-tooltip.click="sku.description" | |||||
> | |||||
<svg-icon icon="info-circle"></svg-icon> | <svg-icon icon="info-circle"></svg-icon> | ||||
<span class="sr-only">More information</span> | <span class="sr-only">More information</span> | ||||
</button> | </button> | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
</tbody> | </tbody> | ||||
</table> | </table> | ||||
<small v-if="discount > 0" class="hint"> | <small v-if="discount > 0" class="hint"> | ||||
<hr class="m-0"> | <hr class="m-0" /> | ||||
¹ applied discount: {{ discount }}% - {{ discount_description }} | ¹ applied discount: {{ discount }}% - | ||||
{{ discount_description }} | |||||
</small> | </small> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Submit</button> | <div v-if="tab == 'advanced'"> | ||||
<div class="form-group row"> | |||||
<label class="col-sm-4">Greylisting</label> | |||||
<div class="col-sm-8"> | |||||
<input | |||||
class="form-check-input" | |||||
type="checkbox" | |||||
/> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<button class="btn btn-primary mt-1" type="submit"> | |||||
<svg-icon icon="check"></svg-icon> Submit | |||||
</button> | |||||
</form> | </form> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import ListInput from '../Widgets/ListInput' | import ListInput from "../Widgets/ListInput"; | ||||
import StatusComponent from '../Widgets/Status' | import StatusComponent from "../Widgets/Status"; | ||||
export default { | export default { | ||||
components: { | components: { | ||||
ListInput, | ListInput, | ||||
StatusComponent | StatusComponent, | ||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
discount: 0, | discount: 0, | ||||
discount_description: '', | discount_description: "", | ||||
user_id: null, | user_id: null, | ||||
user: { aliases: [] }, | user: { aliases: [] }, | ||||
packages: [], | packages: [], | ||||
package_id: null, | package_id: null, | ||||
skus: [], | skus: [], | ||||
status: {} | status: {}, | ||||
} | tab: "general", | ||||
}; | |||||
}, | }, | ||||
created() { | created() { | ||||
this.user_id = this.$route.params.user | this.user_id = this.$route.params.user; | ||||
let wallet = this.$store.state.authInfo.accounts[0] | let wallet = this.$store.state.authInfo.accounts[0]; | ||||
if (!wallet) { | if (!wallet) { | ||||
wallet = this.$store.state.authInfo.wallets[0] | wallet = this.$store.state.authInfo.wallets[0]; | ||||
} | } | ||||
if (wallet && wallet.discount) { | if (wallet && wallet.discount) { | ||||
this.discount = wallet.discount | this.discount = wallet.discount; | ||||
this.discount_description = wallet.discount_description | this.discount_description = wallet.discount_description; | ||||
} | } | ||||
this.$root.startLoading() | this.$root.startLoading(); | ||||
if (this.user_id === 'new') { | if (this.user_id === "new") { | ||||
// do nothing (for now) | // do nothing (for now) | ||||
axios.get('/api/v4/packages') | axios | ||||
.then(response => { | .get("/api/v4/packages") | ||||
this.$root.stopLoading() | .then((response) => { | ||||
this.$root.stopLoading(); | |||||
this.packages = response.data.filter(pkg => !pkg.isDomain) | this.packages = response.data.filter((pkg) => !pkg.isDomain); | ||||
this.package_id = this.packages[0].id | this.package_id = this.packages[0].id; | ||||
}) | }) | ||||
.catch(this.$root.errorHandler) | .catch(this.$root.errorHandler); | ||||
} | } else { | ||||
else { | axios | ||||
axios.get('/api/v4/users/' + this.user_id) | .get("/api/v4/users/" + this.user_id) | ||||
.then(response => { | .then((response) => { | ||||
this.$root.stopLoading() | this.$root.stopLoading(); | ||||
this.user = response.data | this.user = response.data; | ||||
this.user.first_name = response.data.settings.first_name | this.user.first_name = response.data.settings.first_name; | ||||
this.user.last_name = response.data.settings.last_name | this.user.last_name = response.data.settings.last_name; | ||||
this.user.organization = response.data.settings.organization | this.user.organization = response.data.settings.organization; | ||||
this.discount = this.user.wallet.discount | this.discount = this.user.wallet.discount; | ||||
this.discount_description = this.user.wallet.discount_description | this.discount_description = this.user.wallet.discount_description; | ||||
this.status = response.data.statusInfo | this.status = response.data.statusInfo; | ||||
axios.get('/api/v4/users/' + this.user_id + '/skus?type=user') | axios | ||||
.then(response => { | .get("/api/v4/users/" + this.user_id + "/skus?type=user") | ||||
.then((response) => { | |||||
// "merge" SKUs with user entitlement-SKUs | // "merge" SKUs with user entitlement-SKUs | ||||
this.skus = response.data | this.skus = response.data.map((sku) => { | ||||
.map(sku => { | |||||
if (sku.id in this.user.skus) { | if (sku.id in this.user.skus) { | ||||
sku.enabled = true | sku.enabled = true; | ||||
sku.value = this.user.skus[sku.id].count | sku.value = this.user.skus[sku.id].count; | ||||
} else if (!sku.readonly) { | } else if (!sku.readonly) { | ||||
sku.enabled = false | sku.enabled = false; | ||||
} | } | ||||
return sku | return sku; | ||||
}) | }); | ||||
// Update all range inputs (and price) | // Update all range inputs (and price) | ||||
this.$nextTick(() => { | this.$nextTick(() => { | ||||
$('#user-skus input[type=range]').each((idx, elem) => { this.rangeUpdate(elem) }) | $("#user-skus input[type=range]").each((idx, elem) => { | ||||
}) | this.rangeUpdate(elem); | ||||
}); | |||||
}); | |||||
}) | }) | ||||
.catch(this.$root.errorHandler) | .catch(this.$root.errorHandler); | ||||
}) | }) | ||||
.catch(this.$root.errorHandler) | .catch(this.$root.errorHandler); | ||||
} | } | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
$('#first_name').focus() | $("#first_name").focus(); | ||||
}, | }, | ||||
methods: { | methods: { | ||||
submit() { | submit() { | ||||
this.$root.clearFormValidation($('#user-info form')) | this.$root.clearFormValidation($("#user-info form")); | ||||
let method = 'post' | let method = "post"; | ||||
let location = '/api/v4/users' | let location = "/api/v4/users"; | ||||
if (this.user_id !== 'new') { | if (this.user_id !== "new") { | ||||
method = 'put' | method = "put"; | ||||
location += '/' + this.user_id | location += "/" + this.user_id; | ||||
let skus = {} | let skus = {}; | ||||
$('#user-skus input[type=checkbox]:checked').each((idx, input) => { | $("#user-skus input[type=checkbox]:checked").each((idx, input) => { | ||||
let id = $(input).val() | let id = $(input).val(); | ||||
let range = $(input).parents('tr').first().find('input[type=range]').val() | let range = $(input) | ||||
.parents("tr") | |||||
skus[id] = range || 1 | .first() | ||||
}) | .find("input[type=range]") | ||||
this.user.skus = skus | .val(); | ||||
skus[id] = range || 1; | |||||
}); | |||||
this.user.skus = skus; | |||||
} else { | } else { | ||||
this.user.package = this.package_id | this.user.package = this.package_id; | ||||
} | } | ||||
axios[method](location, this.user) | axios[method](location, this.user).then((response) => { | ||||
.then(response => { | |||||
if (response.data.statusInfo) { | if (response.data.statusInfo) { | ||||
this.$store.state.authInfo.statusInfo = response.data.statusInfo | this.$store.state.authInfo.statusInfo = response.data.statusInfo; | ||||
} | } | ||||
this.$toast.success(response.data.message) | this.$toast.success(response.data.message); | ||||
this.$router.push({ name: 'users' }) | this.$router.push({ name: "users" }); | ||||
}) | }); | ||||
}, | }, | ||||
onInputSku(e) { | onInputSku(e) { | ||||
let input = e.target | let input = e.target; | ||||
let sku = this.findSku(input.value) | let sku = this.findSku(input.value); | ||||
let required = [] | let required = []; | ||||
// We use 'readonly', not 'disabled', because we might want to handle | // We use 'readonly', not 'disabled', because we might want to handle | ||||
// input events. For example to display an error when someone clicks | // input events. For example to display an error when someone clicks | ||||
// the locked input | // the locked input | ||||
if (input.readOnly) { | if (input.readOnly) { | ||||
input.checked = !input.checked | input.checked = !input.checked; | ||||
// TODO: Display an alert explaining why it's locked | // TODO: Display an alert explaining why it's locked | ||||
return | return; | ||||
} | } | ||||
// TODO: Following code might not work if we change definition of forbidden/required | // TODO: Following code might not work if we change definition of forbidden/required | ||||
// or we just need more sophisticated SKU dependency rules | // or we just need more sophisticated SKU dependency rules | ||||
if (input.checked) { | if (input.checked) { | ||||
// Check if a required SKU is selected, alert the user if not | // Check if a required SKU is selected, alert the user if not | ||||
(sku.required || []).forEach(title => { | (sku.required || []).forEach((title) => { | ||||
this.skus.forEach(item => { | this.skus.forEach((item) => { | ||||
let checkbox | let checkbox; | ||||
if (item.handler == title && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { | if ( | ||||
item.handler == title && | |||||
(checkbox = $("#s" + item.id).find("input[type=checkbox]")[0]) | |||||
) { | |||||
if (!checkbox.checked) { | if (!checkbox.checked) { | ||||
required.push(item.name) | required.push(item.name); | ||||
} | } | ||||
} | } | ||||
}) | }); | ||||
}) | }); | ||||
if (required.length) { | if (required.length) { | ||||
input.checked = false | input.checked = false; | ||||
return alert(sku.name + ' requires ' + required.join(', ') + '.') | return alert(sku.name + " requires " + required.join(", ") + "."); | ||||
} | } | ||||
} else { | } else { | ||||
// Uncheck all dependent SKUs, e.g. when unchecking Groupware we also uncheck Activesync | // Uncheck all dependent SKUs, e.g. when unchecking Groupware we also uncheck Activesync | ||||
// TODO: Should we display an alert instead? | // TODO: Should we display an alert instead? | ||||
this.skus.forEach(item => { | this.skus.forEach((item) => { | ||||
if (item.required && item.required.indexOf(sku.handler) > -1) { | if (item.required && item.required.indexOf(sku.handler) > -1) { | ||||
$('#s' + item.id).find('input[type=checkbox]').prop('checked', false) | $("#s" + item.id) | ||||
.find("input[type=checkbox]") | |||||
.prop("checked", false); | |||||
} | } | ||||
}) | }); | ||||
} | } | ||||
// Uncheck+lock/unlock conflicting SKUs | // Uncheck+lock/unlock conflicting SKUs | ||||
(sku.forbidden || []).forEach(title => { | (sku.forbidden || []).forEach((title) => { | ||||
this.skus.forEach(item => { | this.skus.forEach((item) => { | ||||
let checkbox | let checkbox; | ||||
if (item.handler == title && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { | if ( | ||||
item.handler == title && | |||||
(checkbox = $("#s" + item.id).find("input[type=checkbox]")[0]) | |||||
) { | |||||
if (input.checked) { | if (input.checked) { | ||||
checkbox.checked = false | checkbox.checked = false; | ||||
checkbox.readOnly = true | checkbox.readOnly = true; | ||||
} else { | } else { | ||||
checkbox.readOnly = false | checkbox.readOnly = false; | ||||
} | } | ||||
} | } | ||||
}) | }); | ||||
}) | }); | ||||
}, | }, | ||||
selectPackage(e) { | selectPackage(e) { | ||||
// Make sure there always is only one package selected | // Make sure there always is only one package selected | ||||
$('#user-packages input').prop('checked', false) | $("#user-packages input").prop("checked", false); | ||||
this.package_id = $(e.target).prop('checked', false).val() | this.package_id = $(e.target).prop("checked", false).val(); | ||||
}, | }, | ||||
rangeUpdate(e) { | rangeUpdate(e) { | ||||
let input = $(e.target || e) | let input = $(e.target || e); | ||||
let value = input.val() | let value = input.val(); | ||||
let record = input.parents('tr').first() | let record = input.parents("tr").first(); | ||||
let sku_id = record.find('input[type=checkbox]').val() | let sku_id = record.find("input[type=checkbox]").val(); | ||||
let sku = this.findSku(sku_id) | let sku = this.findSku(sku_id); | ||||
let cost = sku.cost | let cost = sku.cost; | ||||
// Update the label | // Update the label | ||||
input.prev().text(value + ' ' + sku.range.unit) | input.prev().text(value + " " + sku.range.unit); | ||||
// Update the price | // Update the price | ||||
record.find('.price').text(this.$root.priceLabel(cost, value - sku.units_free, this.discount)) | record | ||||
.find(".price") | |||||
.text( | |||||
this.$root.priceLabel(cost, value - sku.units_free, this.discount) | |||||
); | |||||
}, | }, | ||||
findSku(id) { | findSku(id) { | ||||
for (let i = 0; i < this.skus.length; i++) { | for (let i = 0; i < this.skus.length; i++) { | ||||
if (this.skus[i].id == id) { | if (this.skus[i].id == id) { | ||||
return this.skus[i]; | return this.skus[i]; | ||||
} | } | ||||
} | } | ||||
}, | }, | ||||
statusUpdate(user) { | statusUpdate(user) { | ||||
this.user = Object.assign({}, this.user, user) | this.user = Object.assign({}, this.user, user); | ||||
} | }, | ||||
} | }, | ||||
} | }; | ||||
</script> | </script> |