mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-10 04:20:08 +00:00
Enhance plugin dialog with semver-aware sorting by version, enabling users to sort plugins based on version comparisons.
68 lines
2.7 KiB
JavaScript
68 lines
2.7 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", "version"]);
|
|
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);
|