162 lines
No EOL
6.5 KiB
HTML
162 lines
No EOL
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="https://unpkg.com/buefy/dist/buefy.min.css">
|
|
<style>
|
|
.maillist .tags {
|
|
display: inline;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<section class="section">
|
|
<div class="">
|
|
<div id="app" class="columns">
|
|
<div class="column is-two-fifths">
|
|
<div class="box">
|
|
<b-taginput icon="magnify" placeholder="Search..." expanded v-model="mailSearch" autocomplete
|
|
allow-new :data="mailSearchAutocomplete" @typing="getFilteredMailAddrs" @input="loadMails">
|
|
</b-taginput>
|
|
<b-table :data="mailTable" :loading="mailLoading" narrowed :row-class="() => 'maillist'"
|
|
paginated backend-pagination :total="mailTotal" :per-page="mailLimit"
|
|
@page-change="mailPageChange" @select="mailSelect">
|
|
|
|
<template slot-scope="props">
|
|
<b-table-column field="date" label="Datum">
|
|
{{ props.row.date}}
|
|
</b-table-column>
|
|
<b-table-column field="subject" label="Subject">
|
|
<b-taglist attached>
|
|
<b-tag v-for="tag in props.row.tags" type="is-info">
|
|
{{ tag }}
|
|
</b-tag>
|
|
<b-tag type="is-success">{{ props.row.count }}</b-tag>
|
|
</b-taglist>
|
|
{{ props.row.subject}}
|
|
</b-table-column>
|
|
</template>
|
|
</b-table>
|
|
</div>
|
|
</div>
|
|
<div class="column">
|
|
<div class="box" v-for="message_id in openThread.message_ids" @key="message_id">
|
|
<h2>{{openThread.subject}}</h2>
|
|
<b-taglist attached>
|
|
<b-tag v-for="tag in openThreadMessages[message_id].tags" type="is-info">
|
|
{{ tag }}
|
|
</b-tag>
|
|
</b-taglist>
|
|
<hr>
|
|
<div v-html="openThreadMessages[message_id].body"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://unpkg.com/vue"></script>
|
|
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
|
|
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
|
|
|
<script>
|
|
new Vue({
|
|
el: '#app',
|
|
data: {
|
|
mailTable: [],
|
|
mailSearch: ['tag:inbox'],
|
|
mailLoading: false,
|
|
mailStart: 0,
|
|
mailLimit: 30,
|
|
mailTotal: 0,
|
|
mailRowContent: {},
|
|
mailAddrs: [],
|
|
mailTags: [],
|
|
mailBody: '',
|
|
mailSearchAutocomplete: [],
|
|
searchTimeout: null,
|
|
openThread: {},
|
|
openThreadMessages: [],
|
|
},
|
|
filters: {
|
|
truncate(value) {
|
|
if (value.length > 11) {
|
|
value = value.substring(0, 10) + '…';
|
|
}
|
|
return value;
|
|
},
|
|
},
|
|
methods: {
|
|
|
|
loadMails() {
|
|
this.mailLoading = true;
|
|
search = this.mailSearch.join(' ');
|
|
axios.get(`/search/${search}/${this.mailStart}/${this.mailLimit}`)
|
|
.then(({ data }) => {
|
|
this.mailTable = data.threads;
|
|
this.mailTotal = data.count;
|
|
this.mailLoading = false;
|
|
})
|
|
.catch(({ request }) => {
|
|
this.mailTable = [];
|
|
this.mailTotal = 0;
|
|
this.mailLoading = false;
|
|
})
|
|
},
|
|
|
|
getFilteredMailAddrs(text) {
|
|
kind = text.split(':', 1);
|
|
text = text.substr(text.indexOf(':') + 1);
|
|
axios.get(`/autocomplete/${kind}/${text}`)
|
|
.then(({ data }) => {
|
|
this.mailSearchAutocomplete = data.results.filter((option) => {
|
|
return option.indexOf(text) >= 0;
|
|
});
|
|
})
|
|
},
|
|
|
|
mailPageChange(page) {
|
|
this.mailStart = (page - 1) * this.mailLimit;
|
|
this.loadMails();
|
|
},
|
|
|
|
doMailSearch(search) {
|
|
this.mailSearch = search;
|
|
this.loadMails();
|
|
},
|
|
|
|
debounceSearch(search) {
|
|
if (this.searchTimeout) {
|
|
clearTimeout(this.searchTimeout);
|
|
}
|
|
this.searchTimeout = setTimeout(() => {
|
|
this.doMailSearch(search);
|
|
}, 100);
|
|
},
|
|
|
|
mailSelect(row) {
|
|
axios.get(`/thread/${row.thread_id}`)
|
|
.then(({ data }) => {
|
|
this.openThread = data;
|
|
this.openThreadMessages = {};
|
|
data.message_ids.forEach((messageId) => {
|
|
axios.get(`/message/${encodeURIComponent(messageId)}`)
|
|
.then((data) => { this.$set(this.openThreadMessages, messageId, data.data) })
|
|
})
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
mounted() {
|
|
this.loadMails();
|
|
}
|
|
})
|
|
</script>
|
|
</div>
|
|
</section>
|
|
</body>
|
|
|
|
</html> |