mirror of
https://github.com/axllent/mailpit.git
synced 2025-04-25 12:25:04 +02:00
Feature: Download raw message, HTML/text body parts or attachments via single button
@see #67
This commit is contained in:
parent
2d07683a28
commit
3bb9f4162a
@ -542,6 +542,14 @@ export default {
|
|||||||
self.appInfo = response.data;
|
self.appInfo = response.data;
|
||||||
self.modal('AppInfoModal').show();
|
self.modal('AppInfoModal').show();
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
downloadMessageBody: function (str, ext) {
|
||||||
|
let dl = document.createElement('a');
|
||||||
|
dl.href = "data:text/plain," + encodeURIComponent(str);
|
||||||
|
dl.target = '_blank';
|
||||||
|
dl.download = this.message.ID + '.' + ext;
|
||||||
|
dl.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -575,10 +583,49 @@ export default {
|
|||||||
:href="'#' + messagePrev" title="View previous message">
|
:href="'#' + messagePrev" title="View previous message">
|
||||||
<i class="bi bi-caret-left-fill"></i>
|
<i class="bi bi-caret-left-fill"></i>
|
||||||
</a>
|
</a>
|
||||||
<a :href="'api/v1/message/' + message.ID + '/raw?dl=1'" class="btn btn-outline-light me-2 float-end"
|
<div class="dropdown float-end" id="DownloadBtn">
|
||||||
title="Download message">
|
<button type="button" class="btn btn-outline-light dropdown-toggle" data-bs-toggle="dropdown"
|
||||||
<i class="bi bi-file-arrow-down-fill"></i> <span class="d-none d-md-inline">Download</span>
|
aria-expanded="false">
|
||||||
</a>
|
<i class="bi bi-file-arrow-down-fill"></i>
|
||||||
|
<span class="d-none d-md-inline ms-1">Download</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end">
|
||||||
|
<li>
|
||||||
|
<a :href="'api/v1/message/' + message.ID + '/raw?dl=1'" class="dropdown-item"
|
||||||
|
title="Message source including headers, body and attachments">
|
||||||
|
Raw message
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li v-if="message.HTML">
|
||||||
|
<button v-on:click="downloadMessageBody(message.HTML, 'html')" class="dropdown-item">
|
||||||
|
HTML body
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li v-if="message.Text">
|
||||||
|
<button v-on:click="downloadMessageBody(message.Text, 'txt')" class="dropdown-item">
|
||||||
|
Text body
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li v-if="allAttachments(message).length">
|
||||||
|
<hr class="dropdown-divider">
|
||||||
|
</li>
|
||||||
|
<li v-for="part in allAttachments(message)">
|
||||||
|
<a :href="'api/v1/message/' + message.ID + '/part/' + part.PartID" type="button"
|
||||||
|
class="row m-0 dropdown-item d-flex" target="_blank"
|
||||||
|
:title="part.FileName != '' ? part.FileName : '[ unknown ]'" style="min-width: 350px">
|
||||||
|
<div class="col-auto p-0 pe-1">
|
||||||
|
<i class="bi" :class="attachmentIcon(part)"></i>
|
||||||
|
</div>
|
||||||
|
<div class="col text-truncate p-0 pe-1">
|
||||||
|
{{ part.FileName != '' ? part.FileName : '[ unknown ]' }}
|
||||||
|
</div>
|
||||||
|
<div class="col-auto text-muted small p-0">
|
||||||
|
{{ getFileSize(part.Size) }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col col-md-9 col-lg-5" v-if="!message">
|
<div class="col col-md-9 col-lg-5" v-if="!message">
|
||||||
@ -617,6 +664,7 @@ export default {
|
|||||||
<option value="100">100</option>
|
<option value="100">100</option>
|
||||||
<option value="200">200</option>
|
<option value="200">200</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<span v-if="searching">
|
<span v-if="searching">
|
||||||
<b>{{ formatNumber(items.length) }} result<template v-if="items.length != 1">s</template></b>
|
<b>{{ formatNumber(items.length) }} result<template v-if="items.length != 1">s</template></b>
|
||||||
</span>
|
</span>
|
||||||
@ -678,16 +726,16 @@ export default {
|
|||||||
<button class="list-group-item list-group-item-action" :disabled="!selectedHasUnread()"
|
<button class="list-group-item list-group-item-action" :disabled="!selectedHasUnread()"
|
||||||
v-on:click="markSelectedRead">
|
v-on:click="markSelectedRead">
|
||||||
<i class="bi bi-eye-fill"></i>
|
<i class="bi bi-eye-fill"></i>
|
||||||
Mark selected read
|
Mark read
|
||||||
</button>
|
</button>
|
||||||
<button class="list-group-item list-group-item-action" :disabled="!selectedHasRead()"
|
<button class="list-group-item list-group-item-action" :disabled="!selectedHasRead()"
|
||||||
v-on:click="markSelectedUnread">
|
v-on:click="markSelectedUnread">
|
||||||
<i class="bi bi-eye-slash"></i>
|
<i class="bi bi-eye-slash"></i>
|
||||||
Mark selected unread
|
Mark unread
|
||||||
</button>
|
</button>
|
||||||
<button class="list-group-item list-group-item-action" v-on:click="deleteMessages">
|
<button class="list-group-item list-group-item-action" v-on:click="deleteMessages">
|
||||||
<i class="bi bi-trash-fill me-1 text-danger"></i>
|
<i class="bi bi-trash-fill me-1 text-danger"></i>
|
||||||
Delete selected
|
Delete
|
||||||
</button>
|
</button>
|
||||||
<button class="list-group-item list-group-item-action" v-on:click="selected = []">
|
<button class="list-group-item list-group-item-action" v-on:click="selected = []">
|
||||||
<i class="bi bi-x-circle me-1"></i>
|
<i class="bi bi-x-circle me-1"></i>
|
||||||
|
@ -149,10 +149,6 @@ body.blur {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// .tag.active {
|
|
||||||
// font-weight: bold;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.form-select.tag-selector {
|
.form-select.tag-selector {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -166,6 +162,17 @@ body.blur {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#DownloadBtn {
|
||||||
|
@include media-breakpoint-down(sm) {
|
||||||
|
position: static;
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* PrismJS 1.29.0 - modified!
|
/* PrismJS 1.29.0 - modified!
|
||||||
https://prismjs.com/download.html#themes=prism-coy&languages=markup+css */
|
https://prismjs.com/download.html#themes=prism-coy&languages=markup+css */
|
||||||
code[class*="language-"],
|
code[class*="language-"],
|
||||||
|
@ -211,25 +211,12 @@ export default {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-auto text-md-end mt-md-3">
|
<div class="col-md-auto d-none d-md-block text-end mt-md-3">
|
||||||
<!-- <p class="text-muted small d-none d-md-block mb-2"><small>{{ messageDate(message.Date) }}</small></p>
|
<div class="mt-2 mt-md-0" v-if="allAttachments(message)">
|
||||||
<p class="text-muted small d-none d-md-block"><small>Size: {{ getFileSize(message.Size) }}</small></p> -->
|
<span class="badge rounded-pill text-bg-secondary p-2">
|
||||||
<div class="dropdown mt-2 mt-md-0" v-if="allAttachments(message)">
|
|
||||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
|
||||||
aria-expanded="false">
|
|
||||||
Attachment<span v-if="allAttachments(message).length > 1">s</span>
|
Attachment<span v-if="allAttachments(message).length > 1">s</span>
|
||||||
({{ allAttachments(message).length }})
|
({{ allAttachments(message).length }})
|
||||||
</button>
|
</span>
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li v-for="part in allAttachments(message)">
|
|
||||||
<a :href="'api/v1/message/' + message.ID + '/part/' + part.PartID" type="button"
|
|
||||||
class="dropdown-item" target="_blank">
|
|
||||||
<i class="bi" :class="attachmentIcon(part)"></i>
|
|
||||||
{{ part.FileName != '' ? part.FileName : '[ unknown ]' }}
|
|
||||||
<small class="text-muted ms-2">{{ getFileSize(part.Size) }}</small>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user