Add filters to data bank manager

This commit is contained in:
Cohee 2024-04-16 22:23:59 +03:00
parent 5a614b5173
commit ab5b497562
3 changed files with 132 additions and 66 deletions

View File

@ -620,11 +620,38 @@ async function deleteAttachment(attachment, source, callback) {
*/
async function openAttachmentManager() {
/**
*
* Renders a list of attachments.
* @param {FileAttachment[]} attachments List of attachments
* @param {string} source Source of the attachments
*/
async function renderList(attachments, source) {
/**
* Sorts attachments by sortField and sortOrder.
* @param {FileAttachment} a First attachment
* @param {FileAttachment} b Second attachment
* @returns {number} Sort order
*/
function sortFn(a, b) {
const sortValueA = a[sortField];
const sortValueB = b[sortField];
if (typeof sortValueA === 'string' && typeof sortValueB === 'string') {
return sortValueA.localeCompare(sortValueB) * (sortOrder === 'asc' ? 1 : -1);
}
return (sortValueA - sortValueB) * (sortOrder === 'asc' ? 1 : -1);
}
/**
* Filters attachments by name.
* @param {FileAttachment} a Attachment
* @returns {boolean} True if attachment matches the filter, false otherwise.
*/
function filterFn(a) {
if (!filterString) {
return true;
}
return a.name.toLowerCase().includes(filterString.toLowerCase());
}
const sources = {
[ATTACHMENT_SOURCE.GLOBAL]: '.globalAttachmentsList',
[ATTACHMENT_SOURCE.CHARACTER]: '.characterAttachmentsList',
@ -632,16 +659,37 @@ async function openAttachmentManager() {
};
template.find(sources[source]).empty();
for (const attachment of attachments) {
// Sort attachments by sortField and sortOrder, and apply filter
const sortedAttachmentList = attachments.slice().filter(filterFn).sort(sortFn);
for (const attachment of sortedAttachmentList) {
const attachmentTemplate = template.find('.attachmentListItemTemplate .attachmentListItem').clone();
attachmentTemplate.find('.attachmentListItemName').text(attachment.name);
attachmentTemplate.find('.attachmentListItemSize').text(humanFileSize(attachment.size));
attachmentTemplate.find('.attachmentListItemCreated').text(new Date(attachment.created).toLocaleString());
attachmentTemplate.find('.viewAttachmentButton').on('click', () => openFilePopup(attachment));
attachmentTemplate.find('.deleteAttachmentButton').on('click', () => deleteAttachment(attachment, source, renderAttachments));
template.find(sources[source]).append(attachmentTemplate);
}
}
/**
* Renders buttons for the attachment manager.
* @param {string} source Source of the buttons
*/
function renderButtons(source) {
const sources = {
[ATTACHMENT_SOURCE.GLOBAL]: '.globalAttachmentsTitle',
[ATTACHMENT_SOURCE.CHARACTER]: '.characterAttachmentsTitle',
[ATTACHMENT_SOURCE.CHAT]: '.chatAttachmentsTitle',
};
const buttonsList = template.find('.actionButtonsTemplate .actionButtons').clone();
buttonsList.find('.menu_button').data('attachment-manager-target', source);
template.find(sources[source]).append(buttonsList);
}
async function renderAttachments() {
/** @type {FileAttachment[]} */
const globalAttachments = extension_settings.attachments ?? [];
@ -666,8 +714,14 @@ async function openAttachmentManager() {
template.find('.chatAttachmentsName').text(chatName);
}
let sortField = localStorage.getItem('DataBank_sortField') || 'created';
let sortOrder = localStorage.getItem('DataBank_sortOrder') || 'desc';
let filterString = '';
const hasFandomPlugin = await isFandomPluginAvailable();
const template = $(await renderExtensionTemplateAsync('attachments', 'manager', {}));
renderButtons(ATTACHMENT_SOURCE.GLOBAL);
renderButtons(ATTACHMENT_SOURCE.CHARACTER);
renderButtons(ATTACHMENT_SOURCE.CHAT);
template.find('.scrapeWebpageButton').on('click', function () {
openWebpageScraper(String($(this).data('attachment-manager-target')), renderAttachments);
});
@ -677,6 +731,21 @@ async function openAttachmentManager() {
template.find('.uploadFileButton').on('click', function () {
openFileUploader(String($(this).data('attachment-manager-target')), renderAttachments);
});
template.find('.attachmentSearch').on('input', function () {
filterString = String($(this).val());
renderAttachments();
});
template.find('.attachmentSort').on('change', function () {
if (!(this instanceof HTMLSelectElement) || this.selectedOptions.length === 0) {
return;
}
sortField = this.selectedOptions[0].dataset.sortField;
sortOrder = this.selectedOptions[0].dataset.sortOrder;
localStorage.setItem('DataBank_sortField', sortField);
localStorage.setItem('DataBank_sortOrder', sortOrder);
renderAttachments();
});
await renderAttachments();
callGenericPopup(template, POPUP_TYPE.TEXT, '', { wide: true, large: true, okButton: 'Close' });
}

View File

@ -1,4 +1,4 @@
<div class="wide100p paddingTopBot5">
<div class="wide100p padding5">
<h2 class="marginBot5">
<span data-i18n="Data Bank">
Data Bank
@ -10,31 +10,35 @@
<div data-i18n="Supported file types: Plain Text, PDF, Markdown, HTML." class="marginTopBot5">
Supported file types: Plain Text, PDF, Markdown, HTML.
</div>
<div class="flex-container marginTopBot5">
<input type="search" id="attachmentSearch" class="attachmentSearch text_pole margin0 flex1" placeholder="Search...">
<select id="attachmentSort" class="attachmentSort text_pole margin0 flex1">
<option data-sort-field="created" data-sort-order="desc" data-i18n="Date (Newest First)">
Date (Newest First)
</option>
<option data-sort-field="created" data-sort-order="asc" data-i18n="Date (Oldest First)">
Date (Oldest First)
</option>
<option data-sort-field="name" data-sort-order="asc" data-i18n="Name (A-Z)">
Name (A-Z)
</option>
<option data-sort-field="name" data-sort-order="desc" data-i18n="Name (Z-A)">
Name (Z-A)
</option>
<option data-sort-field="size" data-sort-order="asc" data-i18n="Size (Smallest First)">
Size (Smallest First)
</option>
<option data-sort-field="size" data-sort-order="desc" data-i18n="Size (Largest First)">
Size (Largest First)
</option>
</select>
</div>
<div class="justifyLeft globalAttachmentsBlock marginBot10">
<h3 class="margin0 title_restorable">
<h3 class="globalAttachmentsTitle margin0 title_restorable">
<span data-i18n="Global Attachments">
Global Attachments
</span>
<div class="flex-container flexGap10">
<div class="scrapeWebpageButton menu_button_icon menu_button" data-attachment-manager-target="global" title="Download a page from the web.">
<i class="fa-fw fa-solid fa-globe"></i>
<span data-i18n="From Web">
From Web
</span>
</div>
<div class="scrapeFandomButton menu_button_icon menu_button" data-attachment-manager-target="global" title="Download a page from the Fandom wiki.">
<i class="fa-fw fa-solid fa-fire"></i>
<span data-i18n="From Fandom">
From Fandom
</span>
</div>
<div class="uploadFileButton menu_button_icon menu_button" data-attachment-manager-target="global" title="Upload a file from your computer.">
<i class="fa-fw fa-solid fa-upload"></i>
<span data-i18n="From File">
From File
</span>
</div>
</div>
</h3>
<small data-i18n="These files are available for all characters in all chats.">
These files are available for all characters in all chats.
@ -43,30 +47,10 @@
<hr>
</div>
<div class="justifyLeft characterAttachmentsBlock marginBot10">
<h3 class="margin0 title_restorable">
<h3 class="characterAttachmentsTitle margin0 title_restorable">
<span data-i18n="Character Attachments">
Character Attachments
</span>
<div class="flex-container flexGap10">
<div class="scrapeWebpageButton menu_button_icon menu_button" data-attachment-manager-target="character" title="Download a page from the web.">
<i class="fa-fw fa-solid fa-globe"></i>
<span data-i18n="From Web">
From Web
</span>
</div>
<div class="scrapeFandomButton menu_button_icon menu_button" data-attachment-manager-target="character" title="Download a page from the Fandom wiki.">
<i class="fa-fw fa-solid fa-fire"></i>
<span data-i18n="From Fandom">
From Fandom
</span>
</div>
<div class="uploadFileButton menu_button_icon menu_button" data-attachment-manager-target="character" title="Upload a file from your computer.">
<i class="fa-fw fa-solid fa-upload"></i>
<span data-i18n="From File">
From File
</span>
</div>
</div>
</h3>
<div class="flex-container flexFlowColumn">
<strong><small class="characterAttachmentsName"></small></strong>
@ -78,30 +62,10 @@
<hr>
</div>
<div class="justifyLeft chatAttachmentsBlock marginBot10">
<h3 class="margin0 title_restorable">
<h3 class="chatAttachmentsTitle margin0 title_restorable">
<span data-i18n="Chat Attachments">
Chat Attachments
</span>
<div class="flex-container flexGap10">
<div class="scrapeWebpageButton menu_button_icon menu_button" data-attachment-manager-target="chat" title="Download a page from the web.">
<i class="fa-fw fa-solid fa-globe"></i>
<span data-i18n="From Web">
From Web
</span>
</div>
<div class="scrapeFandomButton menu_button_icon menu_button" data-attachment-manager-target="chat" title="Download a page from the Fandom wiki.">
<i class="fa-fw fa-solid fa-fire"></i>
<span data-i18n="From Fandom">
From Fandom
</span>
</div>
<div class="uploadFileButton menu_button_icon menu_button" data-attachment-manager-target="chat" title="Upload a file from your computer.">
<i class="fa-fw fa-solid fa-upload"></i>
<span data-i18n="From File">
From File
</span>
</div>
</div>
</h3>
<div class="flex-container flexFlowColumn">
<strong><small class="chatAttachmentsName"></small></strong>
@ -116,9 +80,33 @@
<div class="attachmentListItem flex-container alignItemsCenter flexGap10">
<div class="attachmentFileIcon fa-solid fa-file-alt"></div>
<div class="attachmentListItemName flex1"></div>
<small class="attachmentListItemCreated"></small>
<small class="attachmentListItemSize"></small>
<div class="viewAttachmentButton right_menu_button fa-solid fa-magnifying-glass" title="View attachment content"></div>
<div class="deleteAttachmentButton right_menu_button fa-solid fa-trash" title="Delete attachment"></div>
</div>
</div>
<div class="actionButtonsTemplate template_element">
<div class="actionButtons flex-container flexGap10">
<div class="scrapeWebpageButton menu_button_icon menu_button" data-attachment-manager-target="" title="Download a page from the web.">
<i class="fa-fw fa-solid fa-globe"></i>
<span data-i18n="From Web">
From Web
</span>
</div>
<div class="scrapeFandomButton menu_button_icon menu_button" data-attachment-manager-target="" title="Download a page from the Fandom wiki.">
<i class="fa-fw fa-solid fa-fire"></i>
<span data-i18n="From Fandom">
From Fandom
</span>
</div>
<div class="uploadFileButton menu_button_icon menu_button" data-attachment-manager-target="" title="Upload a file from your computer.">
<i class="fa-fw fa-solid fa-upload"></i>
<span data-i18n="From File">
From File
</span>
</div>
</div>
</div>
</div>

View File

@ -18,3 +18,12 @@
.attachmentListItem {
padding: 10px;
}
.attachmentListItemSize {
min-width: 4em;
text-align: right;
}
.attachmentListItemCreated {
text-align: right;
}