This commit is contained in:
Bryce
2025-08-06 21:30:33 -07:00
parent 3387867561
commit d021f045ae
14 changed files with 426 additions and 375 deletions

View File

@@ -54,7 +54,8 @@
<!-- Welcome Section - Only shown when IMAP is not configured -->
{% if not current_user.imap_config %}
{% include "partials/welcome_section.html" %}
{% include "partials/welcome_section.html" %}
<section id="folders-list" class="mb-12"></section>
{% else %}
<!-- Stats Section -->
@@ -81,9 +82,21 @@
<!-- Search and Filter -->
<div class="mb-6 flex justify-between items-center">
<div class="relative w-64">
<input type="text" placeholder="Search folders..." class="input input-bordered w-full pr-10">
<i class="fas fa-search absolute right-3 top-3 text-base-content/50"></i>
<div class="flex items-center space-x-4">
<div class="relative w-64">
<input type="text" placeholder="Search folders..." class="input input-bordered w-full pr-10">
<i class="fas fa-search absolute right-3 top-3 text-base-content/50"></i>
</div>
<div class="flex items-center space-x-2">
<input type="checkbox" id="show-hidden"
name="show_hidden"
class="toggle"
hx-get="/api/folders"
hx-include="this"
hx-target="#folders-list"
hx-swap="outerHTML">
<label for="show-hidden" class="label-text cursor-pointer">Show Hidden</label>
</div>
</div>
<div class="flex space-x-2">
<button class="btn btn-sm btn-outline" hx-get="/api/folders?filter=all" hx-target="#folders-list" hx-swap="outerHTML settle:300ms">All</button>

View File

@@ -44,6 +44,22 @@
<p class="text-base-content/80">{{ folder.rule_text }}</p>
</div>
{% block additional_content %}{% endblock %}
<div class="flex justify-between items-center mt-2">
<div class="flex items-center space-x-2">
<span class="text-xs">Type:</span>
<select
class="select select-bordered select-xs"
hx-put="/api/folders/{{ folder.id }}/type"
hx-target="#folders-list"
hx-swap="innerHTML"
hx-include="this"
name="folder_type"
data-loading-disable >
<option value="tidy" {% if folder.folder_type == 'tidy' %}selected{% endif %}>Tidy</option>
<option value="destination" {% if folder.folder_type == 'destination' %}selected{% endif %}>Destination</option>
<option value="ignore" {% if folder.folder_type == 'ignore' %}selected{% endif %}>Ignore</option>
</select>
</div>
</div>
</div>
</div>

View File

@@ -1,41 +1,5 @@
<div id="folder-{{ folder.id }}" class="card bg-base-100 shadow-xl border border-base-300 hover:shadow-lg">
<div class="card-body" data-loading-states>
<div class="flex justify-between items-start mb-2">
<h3 class="text-xl font-bold truncate flex-grow">{{ folder.name }}</h3>
<div class="flex space-x-2">
<button class="btn btn-sm btn-outline"
hx-get="/api/folders/{{ folder.id }}/edit"
hx-target="#modal-holder"
hx-swap="innerHTML"
hx-trigger="click"
data-loading-disable
>
<i class="fas fa-edit" data-loading-class="!hidden"></i>
<span class="loading loading-spinner loading-xs hidden" data-loading-class-remove="hidden"></span>
</button>
<button class="btn btn-sm btn-outline btn-error fade-me-out"
hx-delete="/api/folders/{{ folder.id }}"
hx-target="#folders-list"
hx-swap="outerhtml settle:300ms"
hx-confirm="Are you sure you want to delete this folder?"
data-loading-disable
>
<i class="fas fa-trash" data-loading-class="!hidden"></i>
<span class="loading loading-spinner loading-xs hidden" data-loading-class-remove="hidden"></span>
</button>
</div>
</div>
<!-- Email count badge for destination folders -->
<div class="flex justify-between items-center mb-2">
<div class="flex space-x-1">
<span class="badge badge-primary">{{ folder.emails_count }} emails</span>
</div>
</div>
<div class="bg-base-200 rounded-box p-4 mb-4">
<p class="text-base-content/80">{{ folder.rule_text }}</p>
</div>
</div>
</div>
{% extends "partials/folder_card_base.html" %}
{% block badges %}
<span class="badge badge-primary">{{ folder.emails_count }} emails</span>
{% endblock %}

View File

@@ -0,0 +1,6 @@
{% extends "partials/folder_card_base.html" %}
{% block badges %}
<span class="badge badge-secondary">Ignored</span>
<span class="badge badge-outline">{{ folder.emails_count }} emails</span>
{% endblock %}

View File

@@ -1,82 +1,20 @@
<div id="folder-{{ folder.id }}" class="card bg-base-100 shadow-xl border border-base-300 hover:shadow-lg">
<div class="card-body" data-loading-states>
<div class="flex justify-between items-start mb-2">
<h3 class="text-xl font-bold truncate flex-grow">{{ folder.name }}</h3>
<div class="flex space-x-2">
<button class="btn btn-sm btn-outline"
hx-get="/api/folders/{{ folder.id }}/edit"
hx-target="#modal-holder"
hx-swap="innerHTML"
hx-trigger="click"
data-loading-disable
>
<i class="fas fa-edit" data-loading-class="!hidden"></i>
<span class="loading loading-spinner loading-xs hidden" data-loading-class-remove="hidden"></span>
</button>
<button class="btn btn-sm btn-outline btn-error fade-me-out"
hx-delete="/api/folders/{{ folder.id }}"
hx-target="#folders-to-tidy-list"
hx-swap="innerHTML swap:1s"
hx-confirm="Are you sure you want to delete this folder?"
data-loading-disable
>
<i class="fas fa-trash" data-loading-class="!hidden"></i>
<span class="loading loading-spinner loading-xs hidden" data-loading-class-remove="hidden"></span>
</button>
</div>
</div>
<!-- Email count badges placed below title but in a separate row -->
<div class="flex justify-between items-center mb-2">
<div class="flex space-x-1">
<span class="badge badge-outline">{{ folder.total_count }} total</span>
{% if folder.pending_count > 0 %}
<button
class="badge badge-warning cursor-pointer"
hx-get="/api/folders/{{ folder.id }}/pending-emails"
hx-target="#modal-holder"
hx-swap="innerHTML"
hx-trigger="click"
title="{{ folder.pending_count }} pending emails"
>
{{ folder.pending_count }} pending
</button>
{% else %}
<span class="badge badge-secondary cursor-pointer" x-tooltip.raw.html="{% if folder.recent_emails %}<table class='text-xs'><tr><th class='text-left pr-2'>Subject</th><th class='text-left'>Date</th></tr>{% for email in folder.recent_emails %}<tr><td class='text-left pr-2 truncate max-w-[150px]'>{{ email.subject }}</td><td class='text-left'>{{ email.date[:10] if email.date else 'N/A' }}</td></tr>{% endfor %}</table>{% else %}No recent emails{% endif %}">{{ folder.pending_count }} pending</span>
{% endif %}
<span class="badge badge-success">{{ folder.total_count - folder.pending_count }} processed</span>
</div>
{% if folder.priority == 1 %}
<span class="badge badge-error">High Priority</span>
{% elif folder.priority == -1 %}
<span class="badge badge-info">Low Priority</span>
{% else %}
<span class="badge badge-primary">Normal Priority</span>
{% endif %}
</div>
<div class="bg-base-200 rounded-box p-4 mb-4">
<p class="text-base-content/80">{{ folder.rule_text }}</p>
</div>
<div class="flex justify-between items-center mt-2">
<div class="flex items-center space-x-2">
<span class="text-xs">Organize:</span>
<input
type="checkbox"
class="toggle toggle-sm toggle-success"
{% if folder.organize_enabled %}checked="checked"{% endif %}
hx-put="/api/folders/{{ folder.id }}/toggle"
hx-target="#folder-{{ folder.id }}"
hx-swap="outerHTML"
hx-trigger="click"
data-loading-disable
aria-label="Toggle organize enabled">
</input>
<span class="loading loading-spinner loading-xs hidden" data-loading-class-remove="hidden"></span>
</div>
</div>
</div>
</div>
{% extends "partials/folder_card_base.html" %}
{% block badges %}
<span class="badge badge-outline">{{ folder.total_count }} total</span>
{% if folder.pending_count > 0 %}
<button
class="badge badge-warning cursor-pointer"
hx-get="/api/folders/{{ folder.id }}/pending-emails"
hx-target="#modal-holder"
hx-swap="innerHTML"
hx-trigger="click"
title="{{ folder.pending_count }} pending emails"
>
{{ folder.pending_count }} pending
</button>
{% else %}
<span class="badge badge-secondary cursor-pointer" x-tooltip.raw.html="{% if folder.recent_emails %}<table class='text-xs'><tr><th class='text-left pr-2'>Subject</th><th class='text-left'>Date</th></tr>{% for email in folder.recent_emails %}<tr><td class='text-left pr-2 truncate max-w-[150px]'>{{ email.subject }}</td><td class='text-left'>{{ email.date[:10] if email.date else 'N/A' }}</td></tr>{% endfor %}</table>{% else %}No recent emails{% endif %}">{{ folder.pending_count }} pending</span>
{% endif %}
<span class="badge badge-success">{{ folder.total_count - folder.pending_count }} processed</span>
{% endblock %}

View File

@@ -0,0 +1,52 @@
<div id="folder-type-modal" class="modal-box" @click.away="$refs.modal.close()">
<h3 class="font-bold text-lg mb-4">Configure Folder Types</h3>
<p class="mb-4">Select the processing type for each folder. Inbox will default to Tidy, while Archive/Spam/Drafts will default to Ignore.</p>
<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Folder Name</th>
<th>Processing Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for folder in folders %}
<tr>
<td>{{ folder.name }}</td>
<td>
<select class="select select-bordered select-sm"
name="folder_type_{{ folder.id }}"
hx-put="/api/folders/{{ folder.id }}/type"
hx-target="#modal-holder"
hx-swap="outerHTML">
<option value="tidy" {% if folder.folder_type == 'tidy' %}selected{% endif %}>Tidy</option>
<option value="destination" {% if folder.folder_type == 'destination' %}selected{% endif %}>Destination</option>
<option value="ignore" {% if folder.folder_type == 'ignore' %}selected{% endif %}>Ignore</option>
</select>
</td>
<td>
{% if folder.folder_type == 'tidy' %}
Processed by AI to organize emails
{% elif folder.folder_type == 'destination' %}
Target for organized emails
{% else %}
Ignored during processing
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="modal-action">
<button type="button" class="btn btn-outline" hx-get="/api/imap/sync" hx-target="#folders-list" hx-swap="outerHTML">
Skip and Use Defaults
</button>
<button type="button" class="btn btn-primary" hx-post="/api/imap/sync" hx-target="#folders-list" hx-swap="outerHTML">
Save and Continue
</button>
</div>
</div>

View File

@@ -1,4 +1,7 @@
<section id="folders-list" class="mb-12">
{% include 'partials/folders_to_tidy_section.html' %}
{% include 'partials/destination_folders_section.html' %}
{% if show_hidden %}
{% include 'partials/hidden_folders_section.html' %}
{% endif %}
</section>

View File

@@ -0,0 +1,27 @@
<div class="hidden-folders-section mb-8" id="hidden-folders">
<div class="section-header bg-base-200 p-4 rounded-t-lg border-b border-base-300">
<div class="flex flex-col md:flex-row md:items-center md:justify-between">
<div>
<h2 class="text-2xl font-bold text-base-content">
<i class="fas fa-eye-slash mr-3"></i>
Hidden Folders
</h2>
<p class="text-base-content/70 mt-1">Folders that are ignored during email processing</p>
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-6">
{% for folder in folders|selectattr('folder_type', 'equalto', 'ignore') %}
{% include 'partials/folder_card_ignore.html' %}
{% else %}
<div class="col-span-full text-center py-12 bg-base-100 rounded-box shadow-lg border border-dashed border-base-300">
<div class="text-5xl mb-4 text-secondary">
<i class="fas fa-folder-slash"></i>
</div>
<h3 class="text-2xl font-bold mb-2">No hidden folders</h3>
<p class="mb-6 text-base-content/70">Folders that are set to ignore will appear here.</p>
</div>
{% endfor %}
</div>
</div>

View File

@@ -80,8 +80,8 @@
{% if success %}
<div class="mt-4 pt-4 border-t border-base-300" data-loading-states>
<button class="btn btn-success w-full" hx-post="/api/imap/sync" hx-target="#folders-list" hx-swap="outerHTML settle:300ms" data-loading-disable>
<span data-loading-class="!hidden"><i class="fas fa-sync mr-2"></i>Sync Folders</span>
<button class="btn btn-success w-full" hx-post="/api/imap/sync" hx-target="#modal-holder" hx-swap="innerHTML" data-loading-disable>
<span data-loading-class="!hidden"><i class="fas fa-sync mr-2"></i>Configure Folder Types</span>
<span class="loading loading-spinner loading-xs hidden" data-loading-class-remove="hidden"></span>
</button>
</div>