Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/User/Info.vue
Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | <div class="container"> | ||||
<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" :value="sku.id" :disabled="sku.readonly" :checked="sku.enabled"> | <input type="checkbox" @input="onInputSku" | ||||
:value="sku.id" | |||||
:disabled="sku.readonly" | |||||
:checked="sku.enabled" | |||||
:dusk="'sku-input-' + sku.title" | |||||
> | |||||
</td> | </td> | ||||
<td class="name"> | <td class="name"> | ||||
<span class="name">{{ sku.name }}</span> | <span class="name">{{ sku.name }}</span> | ||||
<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" | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | export default { | ||||
} | } | ||||
// on new user redirect to users list | // on new user redirect to users list | ||||
if (this.user_id === 'new') { | if (this.user_id === 'new') { | ||||
this.$router.push({ name: 'users' }) | this.$router.push({ name: 'users' }) | ||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
onInputSku(e) { | |||||
let input = e.target | |||||
let sku = this.findSku(input.value) | |||||
let required = [] | |||||
// We use 'readonly', not 'disabled', because we might want to handle | |||||
// input events. For example to display an error when someone clicks | |||||
// the locked input | |||||
if (input.readOnly) { | |||||
input.checked = !input.checked | |||||
// TODO: Display an alert explaining why it's locked | |||||
return | |||||
} | |||||
// TODO: Following code might not work if we change definition of forbidden/required | |||||
// or we just need more sophisticated SKU dependency rules | |||||
if (input.checked) { | |||||
// Check if a required SKU is selected, alert the user if not | |||||
(sku.required || []).forEach(title => { | |||||
this.skus.forEach(item => { | |||||
let checkbox | |||||
if (item.handler == title && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { | |||||
if (!checkbox.checked) { | |||||
required.push(item.name) | |||||
} | |||||
} | |||||
}) | |||||
}) | |||||
if (required.length) { | |||||
input.checked = false | |||||
return alert(sku.name + ' requires ' + required.join(', ') + '.') | |||||
} | |||||
} else { | |||||
// Uncheck all dependent SKUs, e.g. when unchecking Groupware we also uncheck Activesync | |||||
// TODO: Should we display an alert instead? | |||||
this.skus.forEach(item => { | |||||
if (item.required && item.required.indexOf(sku.handler) > -1) { | |||||
$('#s' + item.id).find('input[type=checkbox]').prop('checked', false) | |||||
} | |||||
}) | |||||
} | |||||
// Uncheck+lock/unlock conflicting SKUs | |||||
(sku.forbidden || []).forEach(title => { | |||||
this.skus.forEach(item => { | |||||
let checkbox | |||||
if (item.handler == title && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { | |||||
if (input.checked) { | |||||
checkbox.checked = false | |||||
checkbox.readOnly = true | |||||
} else { | |||||
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, i | let sku = this.findSku(sku_id) | ||||
for (i = 0; i < this.skus.length; i++) { | |||||
if (this.skus[i].id == sku_id) { | |||||
sku = this.skus[i]; | |||||
} | |||||
} | |||||
// 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.price(sku.cost * (value - sku.units_free)) + '/month') | record.find('.price').text(this.$root.price(sku.cost * (value - sku.units_free)) + '/month') | ||||
}, | |||||
findSku(id) { | |||||
for (let i = 0; i < this.skus.length; i++) { | |||||
if (this.skus[i].id == id) { | |||||
return this.skus[i]; | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
// List widget | // List widget | ||||
// TODO: move it to a separate component file when needed | // TODO: move it to a separate component file when needed | ||||
function listinput(elem) | function listinput(elem) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 68 Lines • Show Last 20 Lines |