Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/User/Info.vue
Show All 36 Lines | <div class="container"> | ||||
</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"> | |||||
<label class="col-sm-4 col-form-label">Package</label> | |||||
<div class="col-sm-8"> | |||||
<table class="table form-list"> | |||||
<thead class="thead-light sr-only"> | |||||
<tr> | |||||
<th scope="col"></th> | |||||
<th scope="col">Package</th> | |||||
<th scope="col">Price</th> | |||||
<th scope="col"></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr v-for="pkg in packages" :id="'p' + pkg.id" :key="pkg.id"> | |||||
<td class="selection"> | |||||
<input type="checkbox" :value="pkg.id" @click="selectPackage" :checked="pkg.id == package_id"> | |||||
</td> | |||||
<td>{{ pkg.name }}</td> | |||||
<td class="price text-nowrap"> | |||||
{{ $root.price(pkg.cost) + '/month' }} | |||||
</td> | |||||
<td class="buttons"> | |||||
<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> | |||||
<span class="sr-only">More information</span> | |||||
</button> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
<div v-if="user_id !== 'new'" id="user-skus" class="form-group row"> | |||||
<label class="col-sm-4 col-form-label">Subscriptions</label> | |||||
<div class="col-sm-8"> | |||||
<table class="table form-list"> | |||||
<thead class="thead-light sr-only"> | |||||
<tr> | |||||
<th scope="col"></th> | |||||
<th scope="col">Subscription</th> | |||||
<th scope="col">Price</th> | |||||
<th scope="col"></th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr v-for="sku in skus" :id="'s' + sku.id" :key="sku.id"> | |||||
<td class="selection"> | |||||
<input type="checkbox" :value="sku.id" :disabled="sku.readonly" :checked="sku.enabled"> | |||||
</td> | |||||
<td> | |||||
<span class="name">{{ sku.name }}</span> | |||||
<div v-if="sku.range" class="range-input"> | |||||
<label class="text-nowrap">{{ sku.range.min }} {{ sku.range.unit }}</label> | |||||
<input | |||||
type="range" class="custom-range" @input="rangeUpdate" | |||||
:value="sku.value || sku.range.min" | |||||
:min="sku.range.min" | |||||
:max="sku.range.max" | |||||
> | |||||
</div> | |||||
</td> | |||||
<td class="price text-nowrap"> | |||||
{{ $root.price(sku.cost) + '/month' }} | |||||
</td> | |||||
<td class="buttons"> | |||||
<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> | |||||
<span class="sr-only">More information</span> | |||||
</button> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
<button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Submit</button> | <button class="btn btn-primary" type="submit"><svg-icon icon="check"></svg-icon> Submit</button> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
export default { | export default { | ||||
data() { | data() { | ||||
return { | return { | ||||
user_id: null, | user_id: null, | ||||
user: {} | user: {}, | ||||
packages: [], | |||||
package_id: null, | |||||
skus: [] | |||||
} | } | ||||
}, | }, | ||||
created() { | created() { | ||||
this.user_id = this.$route.params.user | this.user_id = this.$route.params.user | ||||
if (this.user_id === 'new') { | if (this.user_id === 'new') { | ||||
// do nothing (for now) | // do nothing (for now) | ||||
axios.get('/api/v4/packages') | |||||
.then(response => { | |||||
this.packages = response.data.filter(pkg => !pkg.isDomain) | |||||
this.package_id = this.packages[0].id | |||||
}) | |||||
.catch(this.$root.errorHandler) | |||||
} | } | ||||
else { | else { | ||||
axios.get('/api/v4/users/' + this.user_id) | axios.get('/api/v4/users/' + this.user_id) | ||||
.then(response => { | .then(response => { | ||||
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 | ||||
$('#aliases').val(response.data.aliases.join("\n")) | $('#aliases').val(response.data.aliases.join("\n")) | ||||
listinput('#aliases') | listinput('#aliases') | ||||
axios.get('/api/v4/skus') | |||||
.then(response => { | |||||
// "merge" SKUs with user entitlement-SKUs | |||||
this.skus = response.data | |||||
.filter(sku => sku.type == 'user') | |||||
.map(sku => { | |||||
if (sku.id in this.user.skus) { | |||||
sku.enabled = true | |||||
sku.value = this.user.skus[sku.id].count | |||||
} else if (!sku.readonly) { | |||||
sku.enabled = false | |||||
} | |||||
return sku | |||||
}) | |||||
// Update all range inputs (and price) | |||||
this.$nextTick(() => { | |||||
$('#user-skus input[type=range]').each((idx, elem) => { this.rangeUpdate(elem) }) | |||||
}) | |||||
}) | |||||
.catch(this.$root.errorHandler) | |||||
}) | }) | ||||
.catch(this.$root.errorHandler) | .catch(this.$root.errorHandler) | ||||
} | } | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
if (this.user_id === 'new') { | if (this.user_id === 'new') { | ||||
listinput('#aliases') | listinput('#aliases') | ||||
} | } | ||||
$('#first_name').focus() | $('#first_name').focus() | ||||
}, | }, | ||||
methods: { | methods: { | ||||
submit() { | submit() { | ||||
this.$root.clearFormValidation($('#user-info form')) | this.$root.clearFormValidation($('#user-info form')) | ||||
this.user.aliases = $('#aliases').val().split("\n") | this.user.aliases = $('#aliases').val().split("\n") | ||||
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 = {} | |||||
$('#user-skus input[type=checkbox]:checked').each((idx, input) => { | |||||
let id = $(input).val() | |||||
let range = $(input).parents('tr').first().find('input[type=range]').val() | |||||
skus[id] = range || 1 | |||||
}) | |||||
this.user.skus = skus | |||||
} else { | |||||
this.user.package = this.package_id | |||||
} | } | ||||
axios[method](location, this.user) | axios[method](location, this.user) | ||||
.then(response => { | .then(response => { | ||||
delete this.user.password | delete this.user.password | ||||
delete this.user.password_confirm | delete this.user.password_confirm | ||||
if (response.data.status == 'success') { | if (response.data.status == 'success') { | ||||
this.$toastr('success', response.data.message) | this.$toastr('success', response.data.message) | ||||
} | } | ||||
// 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' }) | ||||
} | } | ||||
}) | }) | ||||
}, | |||||
selectPackage(e) { | |||||
// Make sure there always is only one package selected | |||||
$('#user-packages input').prop('checked', false) | |||||
this.package_id = $(e.target).prop('checked', false).val() | |||||
}, | |||||
rangeUpdate(e) { | |||||
let input = $(e.target || e) | |||||
let value = input.val() | |||||
let record = input.parents('tr').first() | |||||
let sku_id = record.attr('id') | |||||
let sku, i | |||||
for (i = 0; i < this.skus.length; i++) { | |||||
if (this.skus[i].id == sku_id) { | |||||
sku = this.skus[i]; | |||||
} | |||||
} | |||||
// Update the label | |||||
input.prev().text(value + ' ' + sku.range.unit) | |||||
// Update the price | |||||
record.find('.price').text(this.$root.price(sku.cost * (value - sku.units_free)) + '/month') | |||||
} | } | ||||
} | } | ||||
} | } | ||||
// 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 |