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"> | ||||
<list-search :placeholder="$t('invitation.search')" :on-search="searchInvitations"></list-search> | <list-search :placeholder="$t('invitation.search')" :on-search="searchInvitations"></list-search> | ||||
<btn class="btn-success create-invite ms-1" @click="inviteUserDialog" icon="envelope-open-text">{{ $t('invitation.create') }}</btn> | <btn class="btn-success create-invite ms-1" @click="$refs.createDialog.show()" icon="envelope-open-text">{{ $t('invitation.create') }}</btn> | ||||
</div> | </div> | ||||
<list-table id="invitations-list" :list="invitations" :setup="setup"> | <list-table id="invitations-list" :list="invitations" :setup="setup"> | ||||
<template v-slot:email="{ item }"> | <template v-slot:email="{ item }"> | ||||
<svg-icon icon="envelope-open-text" :class="statusClass(item)" :title="$t('invitation.status-' + statusLabel(item))"></svg-icon> | <svg-icon icon="envelope-open-text" :class="statusClass(item)" :title="$t('invitation.status-' + statusLabel(item))"></svg-icon> | ||||
<span>{{ item.email }}</span> | <span>{{ item.email }}</span> | ||||
</template> | </template> | ||||
<template v-slot:buttons="{ item }"> | <template v-slot:buttons="{ item }"> | ||||
<btn class="text-danger button-delete p-0 ms-1" @click="deleteInvite(item.id)" icon="trash-can"> | <btn class="text-danger button-delete p-0 ms-1" @click="deleteInvite(item.id)" icon="trash-can"> | ||||
<span class="btn-label">{{ $t('btn.delete') }}</span> | <span class="btn-label">{{ $t('btn.delete') }}</span> | ||||
</btn> | </btn> | ||||
<btn class="button-resend p-0 ms-1" :disabled="item.isNew || item.isCompleted" @click="resendInvite(item.id)" icon="rotate-left"> | <btn class="button-resend p-0 ms-1" :disabled="item.isNew || item.isCompleted" @click="resendInvite(item.id)" icon="rotate-left"> | ||||
<span class="btn-label">{{ $t('btn.resend') }}</span> | <span class="btn-label">{{ $t('btn.resend') }}</span> | ||||
</btn> | </btn> | ||||
</template> | </template> | ||||
</list-table> | </list-table> | ||||
<list-more v-if="hasMore" :on-click="loadInvitations"></list-more> | <list-more v-if="hasMore" :on-click="loadInvitations"></list-more> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div id="invite-create" class="modal" tabindex="-1" role="dialog"> | <modal-dialog id="invite-create" ref="createDialog" :title="$t('invitation.create-title')" @click="inviteUser()" | ||||
<div class="modal-dialog" role="document"> | :buttons="[{ className: 'btn-primary modal-action', icon: 'paper-plane', label: 'invitation.send' }]" | ||||
<div class="modal-content"> | > | ||||
<div class="modal-header"> | |||||
<h5 class="modal-title">{{ $t('invitation.create-title') }}</h5> | |||||
<btn class="btn-close" data-bs-dismiss="modal" :aria-label="$t('btn.close')"></btn> | |||||
</div> | |||||
<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> | <div> | ||||
<input id="file" type="file" class="form-control" name="csv"> | <input id="file" type="file" class="form-control" name="csv"> | ||||
</div> | </div> | ||||
</form> | </form> | ||||
</div> | </modal-dialog> | ||||
<div class="modal-footer"> | |||||
<btn class="btn-secondary modal-cancel" data-bs-dismiss="modal">{{ $t('btn.cancel') }}</btn> | |||||
<btn class="btn-primary modal-action" icon="paper-plane" @click="inviteUser()">{{ $t('invitation.send') }}</btn> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { Modal } from 'bootstrap' | |||||
import ListTools from '../Widgets/ListTools' | import ListTools from '../Widgets/ListTools' | ||||
import ModalDialog from '../Widgets/ModalDialog' | |||||
import { library } from '@fortawesome/fontawesome-svg-core' | import { library } from '@fortawesome/fontawesome-svg-core' | ||||
library.add( | library.add( | ||||
require('@fortawesome/free-solid-svg-icons/faEnvelopeOpenText').definition, | require('@fortawesome/free-solid-svg-icons/faEnvelopeOpenText').definition, | ||||
require('@fortawesome/free-solid-svg-icons/faPaperPlane').definition, | require('@fortawesome/free-solid-svg-icons/faPaperPlane').definition, | ||||
require('@fortawesome/free-solid-svg-icons/faRotateLeft').definition, | require('@fortawesome/free-solid-svg-icons/faRotateLeft').definition, | ||||
) | ) | ||||
export default { | export default { | ||||
components: { | |||||
ModalDialog | |||||
}, | |||||
mixins: [ ListTools ], | mixins: [ ListTools ], | ||||
data() { | data() { | ||||
return { | return { | ||||
invitations: [], | invitations: [], | ||||
setup: { | setup: { | ||||
buttons: true, | buttons: true, | ||||
model: 'invitation', | model: 'invitation', | ||||
columns: [ | columns: [ | ||||
Show All 9 Lines | export default { | ||||
} | } | ||||
] | ] | ||||
} | } | ||||
} | } | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
this.loadInvitations({ init: true }) | this.loadInvitations({ init: true }) | ||||
$('#invite-create')[0].addEventListener('shown.bs.modal', event => { | this.$refs.createDialog.events({ | ||||
$('input', event.target).first().focus() | show: (event) => { | ||||
const form = $(event.target).find('form') | |||||
form.get(0).reset() | |||||
this.fileChange({ target: form.find('#file')[0] }) // resets file input label | |||||
} | |||||
}) | }) | ||||
}, | }, | ||||
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 30 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') { | ||||
this.dialog.hide() | this.$refs.createDialog.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() { | |||||
const dialog = $('#invite-create')[0] | |||||
const form = $('form', dialog) | |||||
form.get(0).reset() | |||||
this.fileChange({ target: form.find('#file')[0] }) // resets file input label | |||||
this.$root.clearFormValidation(form) | |||||
this.dialog = new Modal(dialog) | |||||
this.dialog.show() | |||||
}, | |||||
loadInvitations(params) { | loadInvitations(params) { | ||||
this.listSearch('invitations', '/api/v4/invitations', params) | this.listSearch('invitations', '/api/v4/invitations', params) | ||||
}, | }, | ||||
resendInvite(id) { | resendInvite(id) { | ||||
axios.post('/api/v4/invitations/' + id + '/resend') | axios.post('/api/v4/invitations/' + id + '/resend') | ||||
.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 20 Lines • Show All 45 Lines • Show Last 20 Lines |