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"> | ||||
Signup Invitations | {{ $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="Email address or domain" v-model="search"> | <input class="form-control" type="text" :placeholder="$t('invitation.search')" v-model="search"> | ||||
<div class="input-group-append"> | <div class="input-group-append"> | ||||
<button type="submit" class="btn btn-primary"><svg-icon icon="search"></svg-icon> Search</button> | <button type="submit" class="btn btn-primary"><svg-icon icon="search"></svg-icon> {{ $t('btn.search') }}</button> | ||||
</div> | </div> | ||||
</form> | </form> | ||||
<div> | <div> | ||||
<button class="btn btn-success create-invite ml-1" @click="inviteUserDialog"> | <button class="btn btn-success create-invite ml-1" @click="inviteUserDialog"> | ||||
<svg-icon icon="envelope-open-text"></svg-icon> Create invite(s) | <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 class="thead-light"> | ||||
<tr> | <tr> | ||||
<th scope="col">External Email</th> | <th scope="col">{{ $t('user.ext-email') }}</th> | ||||
<th scope="col">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="statusText(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 ml-1" @click="deleteInvite(inv.id)"> | ||||
<svg-icon icon="trash-alt"></svg-icon> | <svg-icon icon="trash-alt"></svg-icon> | ||||
<span class="btn-label">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 ml-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">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">There are no invitations in the database.</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)">Load 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">Invite for a signup</h5> | <h5 class="modal-title">{{ $t('invitation.create-title') }}</h5> | ||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> | <button type="button" class="close" data-dismiss="modal" :aria-label="$t('btn.close')"> | ||||
<span aria-hidden="true">×</span> | <span aria-hidden="true">×</span> | ||||
</button> | </button> | ||||
</div> | </div> | ||||
<div class="modal-body"> | <div class="modal-body"> | ||||
<form> | <form> | ||||
<p>Enter an email address of the person you want to invite.</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>or</span></div> | <div class="form-separator"><hr><span>{{ $t('form.or') }}</span></div> | ||||
<p> | <p>{{ $t('invitation.create-csv') }}</p> | ||||
To send multiple invitations at once, provide a CSV (comma separated) file, | |||||
or alternatively a plain-text file, containing one email address per line. | |||||
</p> | |||||
<div class="custom-file"> | <div class="custom-file"> | ||||
<input id="file" type="file" class="custom-file-input" name="csv" @change="fileChange"> | <input id="file" type="file" class="custom-file-input" name="csv" @change="fileChange"> | ||||
<label class="custom-file-label" for="file">Choose file...</label> | <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">Cancel</button> | <button type="button" class="btn btn-secondary modal-cancel" data-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> Send invite(s) | <svg-icon icon="paper-plane"></svg-icon> {{ $t('invitation.send') }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
Show All 25 Lines | export default { | ||||
// Remove the invitation record from the list | // Remove the invitation record from the list | ||||
const index = this.invitations.findIndex(item => item.id == id) | const index = this.invitations.findIndex(item => item.id == id) | ||||
this.invitations.splice(index, 1) | this.invitations.splice(index, 1) | ||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
fileChange(e) { | fileChange(e) { | ||||
let label = 'Choose file...' | let label = this.$t('btn.file') | ||||
let files = e.target.files | let files = e.target.files | ||||
if (files.length) { | if (files.length) { | ||||
label = files[0].name | label = files[0].name | ||||
if (files.length > 1) { | if (files.length > 1) { | ||||
label += ', ...' | label += ', ...' | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | export default { | ||||
} | } | ||||
if (invitation.isSent) { | if (invitation.isSent) { | ||||
return 'text-primary' | return 'text-primary' | ||||
} | } | ||||
return '' | return '' | ||||
}, | }, | ||||
statusText(invitation) { | statusLabel(invitation) { | ||||
if (invitation.isCompleted) { | if (invitation.isCompleted) { | ||||
return 'User signed up' | return 'completed' | ||||
} | } | ||||
if (invitation.isFailed) { | if (invitation.isFailed) { | ||||
return 'Sending failed' | return 'failed' | ||||
} | } | ||||
if (invitation.isSent) { | if (invitation.isSent) { | ||||
return 'Sent' | return 'sent' | ||||
} | } | ||||
return 'Not sent yet' | return 'new' | ||||
} | } | ||||
} | } | ||||
} | } | ||||
</script> | </script> |