Move plugin sort from dropdown to clickable column headers

Replace the toolbar sort dropdown with sortable Name/Source/Status column
headers that cycle ascending, descending, then clear. Add a Source column
and a PluginSortKey::None baseline for the cleared state. The whole header
cell is the click target and the sort triangle snaps in without a fade.
This commit is contained in:
Andrew
2026-07-06 14:46:31 +08:00
parent b724cb6631
commit 714fe54f77
8 changed files with 150 additions and 194 deletions

View File

@@ -118,10 +118,6 @@ function ShowExploreMenu() {
if (!exploreMenu || !exploreMenuButton)
return;
// why: our stopPropagation blocks the outside-click handler, so close the sibling sort menu ourselves (mirror of ToggleSortMenu).
if (typeof HideSortMenu === "function")
HideSortMenu();
exploreMenu.hidden = false;
exploreMenuButton.setAttribute("aria-expanded", "true");
}
@@ -220,7 +216,7 @@ function HandleStudio(value) {
SetSelectedInstallAction(payload.install_action, false);
if (typeof NormalizePluginSort === "function") {
pluginSort = NormalizePluginSort(payload.sort_key, payload.sort_order);
RenderSortMenuState();
RenderSortHeaders();
}
ApplyPlugins(payload.data || []);
} else if (payload.command === "status_message") {
@@ -337,6 +333,7 @@ function RenderPlugins() {
row.appendChild(CheckCell(row, plugin));
row.appendChild(LabelCell(plugin, isExpanded, capabilities.length));
row.appendChild(VersionCell(plugin));
row.appendChild(SourceCell(plugin));
row.appendChild(StatusCell(plugin));
block.appendChild(row);
@@ -531,11 +528,24 @@ function LabelCell(plugin, isExpanded = false, capabilityCount = 0) {
nameWrap.appendChild(countBadge);
}
labelCell.appendChild(nameWrap);
labelCell.appendChild(SourceBadge(plugin.source));
return labelCell;
}
function SourceCell(plugin) {
const cell = document.createElement("span");
const normalized = String(plugin.source || "").toLowerCase();
const variant = (normalized === "mine" || normalized === "subscribed") ? normalized : "local";
cell.className = `source-cell source-${variant}`;
const sourceLabel = document.createElement("span");
sourceLabel.className = "source-label";
sourceLabel.textContent = SourceLabel(plugin.source);
cell.appendChild(sourceLabel);
return cell;
}
function RenderCapabilityTree(plugin, capabilities) {
const tree = document.createElement("div");
tree.className = "capabilities-tree";
@@ -574,6 +584,11 @@ function RenderCapabilityRow(plugin, capability, isLast) {
typeCell.textContent = String(capability?.type || "-");
row.appendChild(typeCell);
// why: empty placeholder for the new Source column so the run-action cell stays under Status.
const sourceSpacer = document.createElement("span");
sourceSpacer.className = "capability-source-cell";
row.appendChild(sourceSpacer);
const actionsCell = document.createElement("span");
actionsCell.className = "capability-actions-cell";
const capabilityName = String(capability?.name || "");