SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit 4c2ddcca authored by Jean-Sébastien Caux's avatar Jean-Sébastien Caux
Browse files

Include by-account message listing

parent 4677660d
No related branches found
No related tags found
No related merge requests found
......@@ -87,7 +87,8 @@ class StoredMessageFilterBackend(filters.BaseFilterBackend):
query_raw, ['body-plain', '%%%s%%' % body, 'body-html', '%%%s%%' % body])]
queryfilter = queryfilter | Q(pk__in=sm_ids)
return queryset.filter(queryfilter).filter_for_user(request.user)
return queryset.filter(queryfilter).filter_for_user(
request.user, request.query_params.get('account'))
class StoredMessageListAPIView(ListAPIView):
......
......@@ -9,7 +9,7 @@ class StoredMessageQuerySet(models.QuerySet):
"""
All StoredMessage querysets are always filtered for the user.
"""
def filter_for_user(self, user):
def filter_for_user(self, user, email):
"""
Either su or staff, or user's email account accesses overlap with sender/recipients.
"""
......@@ -19,9 +19,10 @@ class StoredMessageQuerySet(models.QuerySet):
return self
# Filter based on account accesses
if user.email_account_accesses.all().exists():
if user.email_account_accesses.filter(account__email=email).exists():
queryfilter = models.Q()
for access in user.email_account_accesses.all():
for access in user.email_account_accesses.filter(account__email=email):
print("access found: %s" % access.account.email)
queryfilter = queryfilter | (
(models.Q(data__sender__icontains=access.account.email) |
models.Q(data__recipients__icontains=access.account.email))
......
import Vue from 'vue';
import BootstrapVue from 'bootstrap-vue';
Vue.use(BootstrapVue);
import 'bootstrap-vue/dist/bootstrap-vue.css';
import UserAccountsTable from './components/Accounts.vue'
new Vue({
render: h => h(UserAccountsTable),
}).$mount('#user-accounts-table');
<template>
<div class="overflow-auto">
<b-card bg-variant="light">
<b-form-group>
<div v-for="access in accesses">
<input
type="radio"
v-model="accountSelected"
:id="access"
:value="access.account.email"
>
{{ access.account.email }}
</div>
<!-- <b-form-checkbox-group -->
<!-- v-model="accountSelected"> -->
<!-- <b-form-checkbox v-for="account in accounts" :value="account.email"> -->
<!-- {{ account }} -->
<!-- </b-form-checkbox> -->
<!-- </b-form-checkbox-group> -->
</b-form-group>
<p>Account to display: {{ accountSelected }}</p>
</b-card>
</div>
</template>
<script>
export default {
name: "user-accounts-table",
data() {
return {
accesses: null,
accountSelected: null,
}
},
methods: {
fetchAccounts () {
fetch('/mail/api/user_account_accesses')
.then(stream => stream.json())
.then(data => this.accesses = data.results)
.catch(error => console.error(error))
}
},
mounted() {
this.fetchAccounts()
},
}
</script>
<template>
<div class="overflow-auto">
<b-card bg-variant="light">
<b-row class="mb-0">
<div>
<h2>Click on an account to view messages</h2>
<b-list-group>
<b-list-group-item
v-for="access in accesses"
v-bind:class="{'active': isSelected(access.account.email)}"
v-on:click="accountSelected = access.account.email"
v-on:change=""
class="p-2 m-0"
>
{{ access.account.email }}
</b-list-group-item>
</b-list-group>
<div v-if="accountSelected" :key="accountSelected">
<b-row class="mt-4">
<b-col class="col-lg-7">
<b-form-group
label="Filter:"
label-cols-sm="3"
label-align-sm="right"
label-size="sm"
<h2>Messages for Account: <strong>{{ accountSelected }}</strong></h2>
</b-col>
<b-col class="col-lg-5">
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
class="m-2"
align="center"
aria-controls="my-table"
>
<b-input-group size="sm">
<b-form-input
v-model="filter"
type="search"
id="filterInput"
placeholder="Type to search"
</b-pagination>
<p align="center">{{ totalRows }} messages</p>
</b-col>
</b-row>
<b-card bg-variant="light">
<b-row class="mb-0">
<b-col class="col-lg-7">
<b-form-group
label="Filter:"
label-cols-sm="3"
label-align-sm="right"
label-size="sm"
>
<b-input-group size="sm">
<b-form-input
v-model="filter"
type="search"
id="filterInput"
placeholder="Type to search"
>
</b-form-input>
<b-input-group-append>
<b-button :disabled="!filter" @click="filter = ''">Clear</b-button>
</b-input-group-append>
</b-input-group>
</b-form-group>
<b-form-group
label="Time period:"
label-cols-sm="3"
label-align-sm="right"
label-size="sm"
class="mb-0"
>
<b-form-radio-group
v-model="timePeriod"
:options="timePeriodOptions"
>
</b-form-input>
<b-input-group-append>
<b-button :disabled="!filter" @click="filter = ''">Clear</b-button>
</b-input-group-append>
</b-input-group>
</b-form-group>
<b-form-group
label="Time period:"
label-cols-sm="3"
label-align-sm="right"
label-size="sm"
class="mb-0"
>
<b-form-radio-group
v-model="timePeriod"
:options="timePeriodOptions"
</b-form-radio-group>
</b-form-group>
</b-col>
<b-col class="col-lg-5 mb-0">
<b-form-group
label="Filter on:"
label-cols-sm="3"
label-align-sm="right"
label-size="sm"
description="Leave all unchecked to filter on all data"
class="mb-0"
>
</b-form-radio-group>
</b-form-group>
</b-col>
<b-col class="col-lg-5 mb-0">
<b-form-group
label="Filter on:"
label-cols-sm="3"
label-align-sm="right"
label-size="sm"
description="Leave all unchecked to filter on all data"
class="mb-0"
>
<b-form-checkbox-group
v-model="filterOn"
class="mt-1 mb-0">
<b-form-checkbox value="from">From</b-form-checkbox>
<b-form-checkbox value="recipients">Recipients</b-form-checkbox>
<b-form-checkbox value="subject">Subject</b-form-checkbox>
<b-form-checkbox value="body">Message body</b-form-checkbox>
</b-form-checkbox-group>
</b-form-group>
</b-col>
</b-row>
</b-card>
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
class="m-2"
align="center"
aria-controls="my-table"
>
</b-pagination>
<p align="center">{{ totalRows }} messages</p>
<b-table
id="my-table"
:items="messagesProvider"
:fields="fields"
:filter="filter"
:filterIncludedFields="filterOn"
@filtered="onFiltered"
:per-page="perPage"
:current-page="currentPage"
>
<template v-slot:cell(actions)="row">
<b-button size="sm" @click="row.toggleDetails">
{{ row.detailsShowing ? 'Hide' : 'Show' }}
</b-button>
</template>
<template v-slot:row-details="row">
<message-content :message=row.item class="m-2 mb-4"></message-content>
</template>
</b-table>
<b-form-checkbox-group
v-model="filterOn"
class="mt-1 mb-0">
<b-form-checkbox value="from">From</b-form-checkbox>
<b-form-checkbox value="recipients">Recipients</b-form-checkbox>
<b-form-checkbox value="subject">Subject</b-form-checkbox>
<b-form-checkbox value="body">Message body</b-form-checkbox>
</b-form-checkbox-group>
</b-form-group>
</b-col>
</b-row>
</b-card>
<b-table
id="my-table"
:items="messagesProvider"
:fields="fields"
:filter="filter"
:filterIncludedFields="filterOn"
@filtered="onFiltered"
:per-page="perPage"
:current-page="currentPage"
>
<template v-slot:cell(actions)="row">
<b-button size="sm" @click="row.toggleDetails">
{{ row.detailsShowing ? 'Hide' : 'Show' }}
</b-button>
</template>
<template v-slot:row-details="row">
<message-content :message=row.item class="m-2 mb-4"></message-content>
</template>
</b-table>
</div>
</div>
</template>
......@@ -100,6 +124,8 @@ export default {
},
data() {
return {
accesses: null,
accountSelected: null,
perPage: 10,
currentPage: 1,
totalRows: 1,
......@@ -122,11 +148,21 @@ export default {
}
},
methods: {
fetchAccounts () {
fetch('/mail/api/user_account_accesses')
.then(stream => stream.json())
.then(data => this.accesses = data.results)
.catch(error => console.error(error))
},
isSelected: function (selection) {
return selection === this.accountSelected
},
messagesProvider(ctx) {
var params = '?account=' + this.accountSelected
// Our API uses limit/offset pagination
var params = '?limit=' + ctx.perPage + '&offset=' + ctx.perPage * (ctx.currentPage - 1)
params += '&limit=' + ctx.perPage + '&offset=' + ctx.perPage * (ctx.currentPage - 1)
// Add search time period
params += '&' + 'period=' + this.timePeriod
params += '&period=' + this.timePeriod
// Add search query (if it exists)
if (this.filter) {
var filterlist = ['from', 'recipients', 'subject', 'body']
......@@ -151,7 +187,10 @@ export default {
this.totalRows = filteredItems.length
this.currentPage = 1
}
}
},
mounted() {
this.fetchAccounts()
},
}
</script>
......@@ -10,7 +10,7 @@
{% block content %}
<h3>Your email account accesses</h3>
<table class="table">
<table class="table mb-4">
<tr>
<th>Account</th>
<th>Rights</th>
......@@ -19,7 +19,8 @@
</tr>
{% for access in request.user.email_account_accesses.all %}
<tr>
<td>{{ access.account }}</td>
<td>{{ access.account.name }}</td>
<td>{{ access.account.email }}</td>
<td>{{ access.get_rights_display }}</td>
<td>{{ access.date_from }}</td>
<td>{{ access.date_until }}</td>
......@@ -29,14 +30,6 @@
{% endfor %}
</table>
<h3>Accounts</h3>
<div id="user-accounts-table">
<user-accounts-table></user-accounts-table>
</div>
<h3>Messages</h3>
<div id="messages-table">
<messages-table></messages-table>
</div>
......
......@@ -15,8 +15,8 @@ class StoredMessageListView(ListView):
model = StoredMessage
template_name = 'apimail/message_list.html'
def get_queryset(self):
return StoredMessage.objects.filter_for_user(self.request.user)
# def get_queryset(self):
# return StoredMessage.objects.filter_for_user(self.request.user)
def attachment_file(request, uuid, pk):
......
......@@ -20,7 +20,6 @@ module.exports = {
"./scipost/static/scipost/assets/js/newsticker.js",
],
vue: [
"./apimail/static/apimail/assets/vue/accounts_table.js",
"./apimail/static/apimail/assets/vue/messages_table.js",
],
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment