Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/Reseller/Invitations.vue
<template> | <template> | ||||
<div class="container"> | <div class="container"> | ||||
<div class="card" id="invitations"> | <div class="card" id="invitations"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<div class="card-title"> | <div class="card-title"> | ||||
{{ $t('invitation.title') }} | {{ $t('invitation.title') }} | ||||
</div> | </div> | ||||
<div class="card-text"> | <div class="card-text"> | ||||
<div class="mb-2 d-flex"> | <div class="mb-2 d-flex"> | ||||
<form @submit.prevent="searchInvitations" id="search-form" class="input-group" style="flex:1"> | <form @submit.prevent="searchInvitations" id="search-form" class="input-group" style="flex:1"> | ||||
<input class="form-control" type="text" :placeholder="$t('invitation.search')" v-model="search"> | <input class="form-control" type="text" :placeholder="$t('invitation.search')" v-model="search"> | ||||
<div class="input-group-append"> | |||||
<button type="submit" class="btn btn-primary"><svg-icon icon="search"></svg-icon> {{ $t('btn.search') }}</button> | <button type="submit" class="btn btn-primary"><svg-icon icon="search"></svg-icon> {{ $t('btn.search') }}</button> | ||||
</div> | |||||
</form> | </form> | ||||
<div> | <div> | ||||
<button class="btn btn-success create-invite ml-1" @click="inviteUserDialog"> | <button class="btn btn-success create-invite ms-1" @click="inviteUserDialog"> | ||||
<svg-icon icon="envelope-open-text"></svg-icon> {{ $t('invitation.create') }} | <svg-icon icon="envelope-open-text"></svg-icon> {{ $t('invitation.create') }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<table id="invitations-list" class="table table-sm table-hover"> | <table id="invitations-list" class="table table-sm table-hover"> | ||||
<thead class="thead-light"> | <thead> | ||||
<tr> | <tr> | ||||
<th scope="col">{{ $t('user.ext-email') }}</th> | <th scope="col">{{ $t('user.ext-email') }}</th> | ||||
<th scope="col">{{ $t('form.created') }}</th> | <th scope="col">{{ $t('form.created') }}</th> | ||||
<th scope="col"></th> | <th scope="col"></th> | ||||
</tr> | </tr> | ||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<tr v-for="inv in invitations" :id="'i' + inv.id" :key="inv.id"> | <tr v-for="inv in invitations" :id="'i' + inv.id" :key="inv.id"> | ||||
<td class="email"> | <td class="email"> | ||||
<svg-icon icon="envelope-open-text" :class="statusClass(inv)" :title="$t('invitation.status-' + statusLabel(inv))"></svg-icon> | <svg-icon icon="envelope-open-text" :class="statusClass(inv)" :title="$t('invitation.status-' + statusLabel(inv))"></svg-icon> | ||||
<span>{{ inv.email }}</span> | <span>{{ inv.email }}</span> | ||||
</td> | </td> | ||||
<td class="datetime"> | <td class="datetime"> | ||||
{{ inv.created }} | {{ inv.created }} | ||||
</td> | </td> | ||||
<td class="buttons"> | <td class="buttons"> | ||||
<button class="btn text-danger button-delete p-0 ml-1" @click="deleteInvite(inv.id)"> | <button class="btn text-danger button-delete p-0 ms-1" @click="deleteInvite(inv.id)"> | ||||
<svg-icon icon="trash-alt"></svg-icon> | <svg-icon icon="trash-alt"></svg-icon> | ||||
<span class="btn-label">{{ $t('btn.delete') }}</span> | <span class="btn-label">{{ $t('btn.delete') }}</span> | ||||
</button> | </button> | ||||
<button class="btn button-resend p-0 ml-1" :disabled="inv.isNew || inv.isCompleted" @click="resendInvite(inv.id)"> | <button class="btn button-resend p-0 ms-1" :disabled="inv.isNew || inv.isCompleted" @click="resendInvite(inv.id)"> | ||||
<svg-icon icon="redo"></svg-icon> | <svg-icon icon="redo"></svg-icon> | ||||
<span class="btn-label">{{ $t('btn.resend') }}</span> | <span class="btn-label">{{ $t('btn.resend') }}</span> | ||||
</button> | </button> | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
</tbody> | </tbody> | ||||
<tfoot class="table-fake-body"> | <tfoot class="table-fake-body"> | ||||
<tr> | <tr> | ||||
<td colspan="3">{{ $t('invitation.empty-list') }}</td> | <td colspan="3">{{ $t('invitation.empty-list') }}</td> | ||||
</tr> | </tr> | ||||
</tfoot> | </tfoot> | ||||
</table> | </table> | ||||
<div class="text-center p-3" id="more-loader" v-if="hasMore"> | <div class="text-center p-3" id="more-loader" v-if="hasMore"> | ||||
<button class="btn btn-secondary" @click="loadInvitations(true)">{{ $t('nav.more') }}</button> | <button class="btn btn-secondary" @click="loadInvitations(true)">{{ $t('nav.more') }}</button> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div id="invite-create" class="modal" tabindex="-1" role="dialog"> | <div id="invite-create" class="modal" tabindex="-1" role="dialog"> | ||||
<div class="modal-dialog" role="document"> | <div class="modal-dialog" role="document"> | ||||
<div class="modal-content"> | <div class="modal-content"> | ||||
<div class="modal-header"> | <div class="modal-header"> | ||||
<h5 class="modal-title">{{ $t('invitation.create-title') }}</h5> | <h5 class="modal-title">{{ $t('invitation.create-title') }}</h5> | ||||
<button type="button" class="close" data-dismiss="modal" :aria-label="$t('btn.close')"> | <button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="$t('btn.close')"></button> | ||||
<span aria-hidden="true">×</span> | |||||
</button> | |||||
</div> | </div> | ||||
<div class="modal-body"> | <div class="modal-body"> | ||||
<form> | <form> | ||||
<p>{{ $t('invitation.create-email') }}</p> | <p>{{ $t('invitation.create-email') }}</p> | ||||
<div> | <div> | ||||
<input id="email" type="text" class="form-control" name="email"> | <input id="email" type="text" class="form-control" name="email"> | ||||
</div> | </div> | ||||
<div class="form-separator"><hr><span>{{ $t('form.or') }}</span></div> | <div class="form-separator"><hr><span>{{ $t('form.or') }}</span></div> | ||||
<p>{{ $t('invitation.create-csv') }}</p> | <p>{{ $t('invitation.create-csv') }}</p> | ||||
<div class="custom-file"> | <div> | ||||
<input id="file" type="file" class="custom-file-input" name="csv" @change="fileChange"> | <input id="file" type="file" class="form-control" name="csv"> | ||||
<label class="custom-file-label" for="file">{{ $t('btn.file') }}</label> | |||||
</div> | </div> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
<div class="modal-footer"> | <div class="modal-footer"> | ||||
<button type="button" class="btn btn-secondary modal-cancel" data-dismiss="modal">{{ $t('btn.cancel') }}</button> | <button type="button" class="btn btn-secondary modal-cancel" data-bs-dismiss="modal">{{ $t('btn.cancel') }}</button> | ||||
<button type="button" class="btn btn-primary modal-action" @click="inviteUser()"> | <button type="button" class="btn btn-primary modal-action" @click="inviteUser()"> | ||||
<svg-icon icon="paper-plane"></svg-icon> {{ $t('invitation.send') }} | <svg-icon icon="paper-plane"></svg-icon> {{ $t('invitation.send') }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { Modal } from 'bootstrap' | |||||
import { library } from '@fortawesome/fontawesome-svg-core' | import { library } from '@fortawesome/fontawesome-svg-core' | ||||
import { faEnvelopeOpenText, faPaperPlane, faRedo } from '@fortawesome/free-solid-svg-icons' | import { faEnvelopeOpenText, faPaperPlane, faRedo } from '@fortawesome/free-solid-svg-icons' | ||||
library.add(faEnvelopeOpenText, faPaperPlane, faRedo) | library.add(faEnvelopeOpenText, faPaperPlane, faRedo) | ||||
export default { | export default { | ||||
data() { | data() { | ||||
return { | return { | ||||
invitations: [], | invitations: [], | ||||
hasMore: false, | hasMore: false, | ||||
page: 1, | page: 1, | ||||
search: '' | search: '' | ||||
} | } | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
this.$root.startLoading() | this.$root.startLoading() | ||||
this.loadInvitations(null, () => this.$root.stopLoading()) | this.loadInvitations(null, () => this.$root.stopLoading()) | ||||
$('#invite-create')[0].addEventListener('shown.bs.modal', event => { | |||||
$('input', event.target).first().focus() | |||||
}) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
deleteInvite(id) { | deleteInvite(id) { | ||||
axios.delete('/api/v4/invitations/' + id) | axios.delete('/api/v4/invitations/' + id) | ||||
.then(response => { | .then(response => { | ||||
if (response.data.status == 'success') { | if (response.data.status == 'success') { | ||||
this.$toast.success(response.data.message) | this.$toast.success(response.data.message) | ||||
Show All 29 Lines | export default { | ||||
let files = dialog.find('#file').get(0).files | let files = dialog.find('#file').get(0).files | ||||
if (files.length) { | if (files.length) { | ||||
post.append('file', files[0]) | post.append('file', files[0]) | ||||
} | } | ||||
axios.post('/api/v4/invitations', post, params) | axios.post('/api/v4/invitations', post, params) | ||||
.then(response => { | .then(response => { | ||||
if (response.data.status == 'success') { | if (response.data.status == 'success') { | ||||
dialog.modal('hide') | this.dialog.hide() | ||||
this.$toast.success(response.data.message) | this.$toast.success(response.data.message) | ||||
if (response.data.count) { | if (response.data.count) { | ||||
this.loadInvitations({ reset: true }) | this.loadInvitations({ reset: true }) | ||||
} | } | ||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
inviteUserDialog() { | inviteUserDialog() { | ||||
let dialog = $('#invite-create') | const dialog = $('#invite-create')[0] | ||||
let form = dialog.find('form') | const form = $('form', dialog) | ||||
form.get(0).reset() | form.get(0).reset() | ||||
this.fileChange({ target: form.find('#file')[0] }) // resets file input label | this.fileChange({ target: form.find('#file')[0] }) // resets file input label | ||||
this.$root.clearFormValidation(form) | this.$root.clearFormValidation(form) | ||||
dialog.on('shown.bs.modal', () => { | this.dialog = new Modal(dialog) | ||||
dialog.find('input').get(0).focus() | this.dialog.show() | ||||
}).modal() | |||||
}, | }, | ||||
loadInvitations(params, callback) { | loadInvitations(params, callback) { | ||||
let loader | let loader | ||||
let get = {} | let get = {} | ||||
if (params) { | if (params) { | ||||
if (params.reset) { | if (params.reset) { | ||||
this.invitations = [] | this.invitations = [] | ||||
▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines |