up
This commit is contained in:
parent
867a2c8ebf
commit
e99de57edc
24 changed files with 11772 additions and 187 deletions
321
web/index.html
321
web/index.html
|
@ -1,199 +1,162 @@
|
|||
<!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;
|
||||
}
|
||||
.maillist .tags {
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<section>
|
||||
<div id="app" class="container">
|
||||
<div class="row">
|
||||
<b-tabs v-model="activeTab">
|
||||
<b-tab-item label="List">
|
||||
<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">
|
||||
|
||||
<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">
|
||||
<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 props.row.tags" type="is-info">
|
||||
<b-tag v-for="tag in openThreadMessages[message_id].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>
|
||||
|
||||
</b-tab-item>
|
||||
<b-tab-item v-for="(thread, thread_id) in mailsOpen"
|
||||
:key="thread_id"
|
||||
>
|
||||
<template slot="header">
|
||||
{{ thread.subject | truncate }}
|
||||
<b-tag rounded>{{ thread.count }}</b-tag>
|
||||
<button type="button"
|
||||
class="delete"
|
||||
@click="closeActiveTab(thread_id)"
|
||||
></button>
|
||||
</template>
|
||||
<div class="box" v-for="message_id in thread.message_ids"
|
||||
key="message_id">
|
||||
<iframe style="width: 100%"
|
||||
:src="`/message/${message_id}`"
|
||||
onload="javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+'px';}(this));"
|
||||
></iframe>
|
||||
</b-taglist>
|
||||
<hr>
|
||||
<div v-html="openThreadMessages[message_id].body"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</b-tab-item>
|
||||
</b-tabs>
|
||||
</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 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,
|
||||
|
||||
activeTab: 0,
|
||||
mailsOpen: {},
|
||||
},
|
||||
filters: {
|
||||
truncate(value) {
|
||||
if (value.length > 11) {
|
||||
value = value.substring(0, 10) + '…';
|
||||
<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();
|
||||
}
|
||||
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);
|
||||
if (text.length == 0) { return; }
|
||||
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}) => {
|
||||
console.log('hello');
|
||||
console.log(data);
|
||||
this.$set(this.mailsOpen, data.thread_id, data);
|
||||
this.$nextTick(() => {
|
||||
pos = Object.keys(this.mailsOpen).indexOf(data.thread_id);
|
||||
this.activeTab = pos + 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
closeActiveTab(thread_id) {
|
||||
delete this.mailsOpen[thread_id];
|
||||
this.mailsOpen = Object.assign({}, this.mailsOpen);
|
||||
this.activeTab--;
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.loadMails();
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</section>
|
||||
})
|
||||
</script>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue