feat(plugins): add sorting, filtering, and fix Update All button (#252)

* feat(store): add sorting, filtering, and fix Update All button

Add client-side sorting and filtering to the Plugin Store:
- Sort by A-Z, Z-A, Verified First, Recently Updated, Category
- Filter by verified, new, installed status, author, and tags
- Installed/Update Available badges on store cards
- Active filter count badge with clear-all button
- Sort preference persisted to localStorage

Fix three bugs causing button unresponsiveness:
- pluginsInitialized never reset on HTMX tab navigation (root cause
  of Update All silently doing nothing on second visit)
- htmx:afterSwap condition too broad (fired on unrelated swaps)
- data-running guard tied to DOM element replaced by cloneNode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(store): replace tag pills with category pills, fix sort dates

- Replace tag filter pills with category filter pills (less duplication)
- Prefer per-plugin last_updated over repo-wide pushed_at for sort

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: add console logging to filter/sort handlers

* fix: bump cache-buster versions for JS and CSS

* feat(plugins): add sorting to installed plugins section

Add A-Z, Z-A, and Enabled First sort options for installed plugins
with localStorage persistence. Both installed and store sections
now default to A-Z sorting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(store): consolidate CSS, fix stale cache bug, add missing utilities, fix icon

- Consolidate .filter-pill and .category-filter-pill into shared selectors
  and scope transition to only changed properties
- Fix applyStoreFiltersAndSort ignoring fresh server-filtered results by
  accepting optional basePlugins parameter
- Add missing .py-1.5 and .rounded-full CSS utility classes
- Replace invalid fa-sparkles with fa-star (FA 6.0.0 compatible)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(store): semver-aware update badge and add missing gap-1.5 utility

- Replace naive version !== comparison with isNewerVersion() that does
  semver greater-than check, preventing false "Update" badges on
  same-version or downgrade scenarios
- Add missing .gap-1.5 CSS utility used by category pills and tag lists

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Chuck <chuck@example.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-02-17 07:38:16 -05:00
committed by GitHub
parent 963c4d3b91
commit 636d0e181c
4 changed files with 477 additions and 42 deletions

View File

@@ -83,6 +83,9 @@
[data-theme="dark"] .hover\:bg-gray-200:hover { background-color: #4b5563; }
[data-theme="dark"] .hover\:text-gray-700:hover { color: #e5e7eb; }
[data-theme="dark"] .hover\:border-gray-300:hover { border-color: #6b7280; }
[data-theme="dark"] .bg-red-100 { background-color: #450a0a; }
[data-theme="dark"] .text-red-700 { color: #fca5a5; }
[data-theme="dark"] .hover\:bg-red-200:hover { background-color: #7f1d1d; }
/* Base styles */
* {
@@ -141,6 +144,7 @@ body {
.rounded-lg { border-radius: 0.5rem; }
.rounded-md { border-radius: 0.375rem; }
.rounded-full { border-radius: 9999px; }
.rounded { border-radius: 0.25rem; }
.shadow { box-shadow: var(--shadow); }
@@ -152,6 +156,7 @@ body {
.p-4 { padding: 1rem; }
.p-2 { padding: 0.5rem; }
.px-4 { padding-left: 1rem; padding-right: 1rem; }
.py-1\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
.pb-4 { padding-bottom: 1rem; }
@@ -199,6 +204,7 @@ body {
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gap-1\.5 { gap: 0.375rem; }
.gap-2 { gap: 0.5rem; }
.gap-3 { gap: 0.75rem; }
.gap-4 { gap: 1rem; }
@@ -663,6 +669,31 @@ button.bg-white {
color: var(--color-purple-text);
}
/* Filter Pill Toggle States */
.filter-pill,
.category-filter-pill {
cursor: pointer;
user-select: none;
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}
.filter-pill[data-active="true"],
.category-filter-pill[data-active="true"] {
background-color: var(--color-info-bg);
border-color: var(--color-info);
color: var(--color-info);
font-weight: 600;
}
.filter-pill[data-active="true"]:hover,
.category-filter-pill[data-active="true"]:hover {
opacity: 0.85;
}
.category-filter-pill[data-active="true"] {
box-shadow: 0 0 0 1px var(--color-info);
}
/* Section Headers with Subtle Gradients */
.section-header {
background: linear-gradient(135deg, rgb(255 255 255 / 90%) 0%, rgb(249 250 251 / 90%) 100%);