Files
OrcaSlicer/resources/web/dialog/PluginsDialog/plugin-sort.js
Andrew 714fe54f77 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.
2026-07-06 15:03:14 +08:00

68 lines
2.6 KiB
JavaScript

// why: C++ owns ordering; this file only sends and reflects sort state.
const DEFAULT_PLUGIN_SORT = { key: "none", order: "asc" };
// note: SORT_FIELDS are the clickable columns. "none" is the baseline/cleared state, not a field -
// it is special-cased in NormalizePluginSort and produced by CyclePluginSort's third click.
const SORT_FIELDS = new Set(["status", "name", "source"]);
let pluginSort = { ...DEFAULT_PLUGIN_SORT };
// why: C++ returns canonical sort state; guard stale or malformed values before reflecting them.
function NormalizePluginSort(sortKey, sortOrder) {
const key = String(sortKey || "");
return {
key: key === "none" ? "none" : (SORT_FIELDS.has(key) ? key : DEFAULT_PLUGIN_SORT.key),
order: sortOrder === "desc" ? "desc" : DEFAULT_PLUGIN_SORT.order,
};
}
function RequestPluginSort(sortKey, sortOrder) {
pluginSort = NormalizePluginSort(sortKey, sortOrder);
RenderSortHeaders();
if (typeof SendMessage === "function")
SendMessage("set_plugin_sort", {
sort_key: pluginSort.key,
sort_order: pluginSort.order,
});
}
// why: one click per column cycles asc -> desc -> clear; setting any column clears the previous
// one for free because C++ (and pluginSort) only ever hold a single key.
function CyclePluginSort(field) {
if (!SORT_FIELDS.has(field))
return;
if (pluginSort.key !== field)
RequestPluginSort(field, "asc");
else if (pluginSort.order === "asc")
RequestPluginSort(field, "desc");
else
RequestPluginSort("none", "asc"); // third click: back to baseline
}
// why: paints the sort indicator for headers
// e.g., when user clicks triangle to change sort order, or change to sort by a new different field
function RenderSortHeaders() {
document.querySelectorAll(".hdr .sort-th").forEach((th) => {
// "" | "asc" | "desc" - renders the triangle via plugin-sort.css [data-sort=...].
th.dataset.sort = th.dataset.sortField === pluginSort.key ? pluginSort.order : "";
});
}
function InitSortHeaders() {
document.querySelectorAll(".hdr .sort-th").forEach((th) => {
th.addEventListener("click", () => CyclePluginSort(th.dataset.sortField));
// note: role="button" cells need Enter/Space to match the old dropdown's keyboard access.
th.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
CyclePluginSort(th.dataset.sortField);
}
});
});
RenderSortHeaders(); // paint the initial state (baseline = no triangle)
}
// why: guarded so the module can be loaded in headless syntax checks.
if (typeof document !== "undefined")
document.addEventListener("DOMContentLoaded", InitSortHeaders);