Add Email Template Editor to Summarize Panel

This commit is contained in:
Guido Kraemer 2025-12-23 13:22:47 +01:00
parent 7eb9a2cf56
commit fe427c29ee
5 changed files with 108 additions and 15 deletions

View file

@ -1008,7 +1008,11 @@
"description": "" "description": ""
}, },
"prompt_summarize_full_text": { "prompt_summarize_full_text": {
"message": "Summarize the following email or emails into a bullet point list. If there are multiple emails, consider the entire thread for the summary.", "message": "Summarize the following email or emails into a bullet point list. If there are multiple emails, consider the entire thread for the summary.\n------------------\n\n",
"description": ""
},
"prompt_summarize_email_template": {
"message": "From: {%author%}\nTo: {%recipients%}\nCC: {%cc_list%}\nSubject: {%mail_subject%}\nDate: {%mail_datetime%}\nAttachments:\n{%mail_attachments_info%}\nBody:\n{%mail_text_body%}\n---------------\n\n",
"description": "" "description": ""
}, },
"prompt_get_task": { "prompt_get_task": {
@ -1075,6 +1079,10 @@
"message": "You can change the prompt as you wish, but the response received from the AI must be in JSON format as specified in the default prompt!", "message": "You can change the prompt as you wish, but the response received from the AI must be in JSON format as specified in the default prompt!",
"description": "" "description": ""
}, },
"prefs_OptionText_Summarize_infoline2": {
"message": "You can change the prompt as you wish, the first field is the main prompt, the second field is the template for a single mail. The list of emails will be appended to the main prompt.",
"description": ""
},
"prefs_OptionText_get_calendar_event_Sparks_not_present": { "prefs_OptionText_get_calendar_event_Sparks_not_present": {
"message": "To use the calendar event and task features, please install the ThunderAI Sparks addon.", "message": "To use the calendar event and task features, please install the ThunderAI Sparks addon.",
"description": "" "description": ""

View file

@ -339,6 +339,22 @@ const specialPrompts = [
api_model: '', api_model: '',
is_default: "1", is_default: "1",
is_special: "1", is_special: "1",
},
{
id: 'prompt_summarize_email_template',
name: "__MSG_prompt_summarize_email_template__",
text: "prompt_summarize_email_template_full_text",
type: "1",
action: "0",
need_selected: "0",
need_signature: "0",
need_custom_text: "0",
define_response_lang: "0",
use_diff_viewer: "0",
api_type: '',
api_model: '',
is_default: "1",
is_special: "1",
} }
]; ];

View file

@ -3,6 +3,10 @@
margin: 20px auto; margin: 20px auto;
} }
#summarize_email_template_text {
width: 100%;
}
#summarize_prompt_text { #summarize_prompt_text {
width: 100%; width: 100%;
} }

View file

@ -12,17 +12,58 @@
<p>__MSG_Summarize_info_default__</p> <p>__MSG_Summarize_info_default__</p>
</div> </div>
<div id="summarize_prompt_container"> <div id="summarize_prompt_container">
<span class="section_title">__MSG_Summarize_prompt_text_title__</span > <!--title and description-->
<span id="summarize_prompt_unsaved" class="unsaved hidden">__MSG_customPrompts_unsaved_changes__</span> <span class="section_title">
<br><span class="infoline">__MSG_prefs_OptionText_btnManagePrompts_infoline__ <a href="https://micz.it/thunderbird-addon-thunderai/data-placeholders/">__MSG_more_info_string__</a> __MSG_Summarize_prompt_text_title__
<br><b>__MSG_prefs_OptionText_AdvancedPromptResponse_infoline2__</b></span> </span>
<br> <br>
<span class="infoline">
__MSG_prefs_OptionText_btnManagePrompts_infoline__
<a href="https://micz.it/thunderbird-addon-thunderai/data-placeholders/">
__MSG_more_info_string__
</a>
<br>
<b>__MSG_prefs_OptionText_Summarize_infoline2__</b>
</span>
<br>
<!--main prompt-->
<div class="autocomplete-container"> <div class="autocomplete-container">
<textarea id="summarize_prompt_text" rows="15"></textarea> <textarea id="summarize_prompt_text" rows="15"></textarea>
<ul class="autocomplete-list hidden"></ul> <ul class="autocomplete-list hidden"></ul>
</div> </div>
<div id="summarize_info_additional_statements"></div> <div id="summarize_info_additional_statements"></div>
<div class="btn_div"><button id="btn_reset_prompt" disabled>__MSG_reset_default__</button><button id="btn_save_prompt" disabled>__MSG_save__</button></div> <div class="btn_div">
<button id="btn_reset_prompt" disabled>
__MSG_reset_default__
</button>
<button id="btn_save_prompt" disabled>
__MSG_save__
</button>
</div>
<!--email template-->
<div class="autocomplete-container">
<textarea id="summarize_email_template_text" rows="15"></textarea>
<ul class="autocomplete-list hidden"></ul>
</div>
<div id="summarize_info_additional_statements"></div>
<div class="btn_div">
<button id="btn_reset_email_template" disabled>
__MSG_reset_default__
</button>
<button id="btn_save_email_template" disabled>
__MSG_save__
</button>
</div>
</div> </div>
<script src="mzta-summarize.js" type="module"></script> <script src="mzta-summarize.js" type="module"></script>
<script src="../../js/mzta-i18n.js"></script> <script src="../../js/mzta-i18n.js"></script>

View file

@ -32,41 +32,65 @@ document.addEventListener("DOMContentLoaded", async () => {
const summarize_textarea = document.getElementById("summarize_prompt_text"); const summarize_textarea = document.getElementById("summarize_prompt_text");
const summarize_save_btn = document.getElementById("btn_save_prompt"); const summarize_save_btn = document.getElementById("btn_save_prompt");
const summarize_reset_btn = document.getElementById("btn_reset_prompt"); const summarize_reset_btn = document.getElementById("btn_reset_prompt");
const summarize_textarea_email_template = document.getElementById("summarize_email_template_text");
const summarize_reset_email_template_btn = document.getElementById("btn_reset_email_template");
const summarize_save_email_template_btn = document.getElementById("btn_save_email_template");
let specialPrompts = await getSpecialPrompts(); let specialPrompts = await getSpecialPrompts();
let summarize_prompt = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize'); let summarize_prompt = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize');
let summarize_email_template = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_template');
summarize_textarea.addEventListener("input", (event) => { summarize_textarea.addEventListener("input", (event) => {
summarize_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_summarize_full_text')); summarize_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_summarize_full_text'));
summarize_save_btn.disabled = (event.target.value === summarize_prompt.text); summarize_save_btn.disabled = (event.target.value === summarize_prompt.text);
if (summarize_save_btn.disabled) {
document.getElementById("summarize_prompt_unsaved").classList.add("hidden");
} else {
document.getElementById("summarize_prompt_unsaved").classList.remove("hidden");
}
}); });
summarize_textarea_email_template.addEventListener("input", (event) => {
summarize_reset_email_template_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_summarize_email_template'));
summarize_save_email_template_btn.disabled = (event.target.value === summarize_email_template.text);
});
summarize_reset_email_template_btn.addEventListener("click", () => {
summarize_textarea_email_template.value = browser.i18n.getMessage("prompt_summarize_email_template");
summarize_reset_email_template_btn.disabled = true;
let event = new Event("input", { bubbles: true, cancelable: true });
summarize_textarea_email_template.dispatchEvent(event);
});
summarize_reset_btn.addEventListener("click", () => { summarize_reset_btn.addEventListener("click", () => {
summarize_textarea.value = browser.i18n.getMessage("prompt_summarize_full_text"); summarize_textarea.value = browser.i18n.getMessage("prompt_summarize_full_text");
summarize_reset_btn.disabled = true; summarize_reset_btn.disabled = true;
let event = new Event("input", { bubbles: true, cancelable: true }); let event = new Event("input", { bubbles: true, cancelable: true });
summarize_textarea.dispatchEvent(event); summarize_textarea.dispatchEvent(event);
}); });
summarize_save_email_template_btn.addEventListener("click", () => {
specialPrompts.find(prompt => prompt.id === 'prompt_summarize_email_template').text = summarize_textarea_email_template.value;
setSpecialPrompts(specialPrompts);
summarize_save_email_template_btn.disabled = true;
browser.runtime.sendMessage({ command: "reload_menus" });
});
summarize_save_btn.addEventListener("click", () => { summarize_save_btn.addEventListener("click", () => {
specialPrompts.find(prompt => prompt.id === 'prompt_summarize').text = summarize_textarea.value; specialPrompts.find(prompt => prompt.id === 'prompt_summarize').text = summarize_textarea.value;
setSpecialPrompts(specialPrompts); setSpecialPrompts(specialPrompts);
summarize_save_btn.disabled = true; summarize_save_btn.disabled = true;
document.getElementById("summarize_prompt_unsaved").classList.add("hidden");
browser.runtime.sendMessage({ command: "reload_menus" }); browser.runtime.sendMessage({ command: "reload_menus" });
}); });
if(summarize_prompt.text === 'prompt_summarize_full_text'){ if(summarize_prompt.text === 'prompt_summarize_full_text'){
summarize_prompt.text = browser.i18n.getMessage(summarize_prompt.text); summarize_prompt.text = browser.i18n.getMessage(summarize_prompt.text);
} }
if(summarize_email_template === 'prompt_summarize_email_template'){
summarize_email_template.text = browser.i18n.getMessage(summarize_email_template.text);
}
summarize_textarea_email_template.value = summarize_email_template.text;
summarize_reset_email_template_btn.disabled = (summarize_email_template.value === browser.i18n.getMessage("prompt_summarize_email_template"));
summarize_textarea.value = summarize_prompt.text; summarize_textarea.value = summarize_prompt.text;
summarize_reset_btn.disabled = (summarize_textarea.value === browser.i18n.getMessage("prompt_summarize_full_text")); summarize_reset_btn.disabled = (summarize_textarea.value === browser.i18n.getMessage("prompt_summarize_full_text"));
autocompleteSuggestions = (await getPlaceholders(true)) autocompleteSuggestions = (await getPlaceholders(true))
.filter((p) => p.id !== "additional_text") .filter((p) => p.id !== "additional_text")
.map((p) => ({ command: `{%${p.id}%}`, type: p.type })); .map((p) => ({ command: `{%${p.id}%}`, type: p.type }));