mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-30 06:41:51 +00:00
feat(web): migrate dashboard checkboxes to @nous-research/ui + DS polish (#28814)
* feat(web): migrate dashboard checkboxes to @nous-research/ui + DS polish Replaces the hand-rolled shadcn-style `Checkbox` in `web/src/components/ui/` with the Nous DS `Checkbox` (Radix-backed) from `@nous-research/ui`, bumps the DS to 0.14.2, and picks up two regressions surfaced by the bump. Checkbox migration - bump `@nous-research/ui` 0.14.0 → ^0.14.2 and remove `web/src/components/ui/checkbox.tsx` - migrate `ProfilesPage` and `ModelPickerDialog` to the DS Checkbox API (`onCheckedChange`, paired `<Label htmlFor>`) - expose `Checkbox` on the dashboard plugin SDK (`web/src/plugins/registry.ts`) so plugin bundles can use the same DS component - migrate the kanban dashboard plugin's 7 native `<input type="checkbox">` call sites to the SDK `Checkbox`, with a native-input fallback shim so the bundle still renders against older hosts that predate the SDK export Fix: missing font registrations after the 0.14.x split - import `@nous-research/ui/styles/fonts.css` before `globals.css` in `web/src/index.css`. As of 0.14.x, `globals.css` only declares the `--font-*` variables (Collapse, Mondwest, Rules Compressed/Expanded); the `@font-face` registrations now live in a separate `fonts.css`, so without this import the DS components silently fall back to a system font stack and look unstyled. Fix: right-align page header toolbars on sm+ viewports - The mobile dashboard polish in #28127 flipped four pages' `setEnd(...)` wrappers from `justify-end` to `w-full ... justify-start` so toolbars stack below the title and align left on small screens. But the outer `end` slot in `PageHeaderProvider` already has `sm:justify-end`, and that has no effect when its only child is `w-full` — once a flex child fills the row, the parent's `justify-*` can't move it. The toolbar pinned to the *left* of the right-side `sm:max-w-md` (~448px) slot, making the buttons appear to float a couple-hundred pixels off the right edge on Analytics, Models, Logs, and Plugins. - Re-add `sm:justify-end` on the inner wrapper of each affected page, preserving the mobile stacked layout. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(nix): update web npmDeps hash for package-lock bump Co-authored-by: Cursor <cursoragent@cursor.com> * fix(nix): refresh npm lockfile hashes * chore(ci): re-trigger checks after nix lockfile hash fix Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
42c4288411
commit
edb2d91057
13 changed files with 282 additions and 207 deletions
58
plugins/kanban/dashboard/dist/index.js
vendored
58
plugins/kanban/dashboard/dist/index.js
vendored
|
|
@ -24,6 +24,23 @@
|
|||
const { useState, useEffect, useCallback, useMemo, useRef } = SDK.hooks;
|
||||
const { cn, timeAgo } = SDK.utils;
|
||||
|
||||
// Newer host dashboards expose a DS-styled Checkbox on the plugin SDK.
|
||||
// Fall back to a native <input type="checkbox"> shim so older hosts that
|
||||
// predate the design-system rollout still render. The shim normalises
|
||||
// Radix's onCheckedChange(checked) signature to native onChange(event).
|
||||
const Checkbox = SDK.components.Checkbox || function (props) {
|
||||
const { checked, onCheckedChange, className, onClick, ...rest } = props;
|
||||
return h("input", Object.assign({
|
||||
type: "checkbox",
|
||||
checked: !!checked,
|
||||
className: className,
|
||||
onClick: onClick,
|
||||
onChange: function (e) {
|
||||
if (onCheckedChange) onCheckedChange(e.target.checked);
|
||||
},
|
||||
}, rest));
|
||||
};
|
||||
|
||||
// useI18n is a hook each component calls locally. Older host dashboards
|
||||
// may not expose it yet; fall back to a shim so the bundle still renders
|
||||
// English against an older host SDK. English fallback strings live
|
||||
|
|
@ -1648,11 +1665,10 @@
|
|||
h(Label, { className: "text-xs text-muted-foreground" },
|
||||
"Orchestration mode"),
|
||||
h("label", { className: "flex items-center gap-2 text-xs h-8" },
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
checked: !!settings.auto_decompose,
|
||||
onChange: function (e) {
|
||||
saveSettings({ auto_decompose: !!e.target.checked });
|
||||
onCheckedChange: function (checked) {
|
||||
saveSettings({ auto_decompose: checked === true });
|
||||
},
|
||||
}),
|
||||
"Auto-decompose triage tasks",
|
||||
|
|
@ -1908,10 +1924,9 @@
|
|||
}),
|
||||
),
|
||||
h("label", { className: "flex items-center gap-2 text-xs" },
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
checked: switchTo,
|
||||
onChange: function (e) { setSwitchTo(e.target.checked); },
|
||||
onCheckedChange: function (checked) { setSwitchTo(checked === true); },
|
||||
}),
|
||||
tx(t, "switchAfterCreate", "Switch to this board after creating it"),
|
||||
),
|
||||
|
|
@ -1981,19 +1996,17 @@
|
|||
),
|
||||
h("label", { className: "flex items-center gap-2 text-xs",
|
||||
title: "Include archived tasks in the board view. Archived tasks are hidden by default." },
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
checked: props.includeArchived,
|
||||
onChange: function (e) { props.setIncludeArchived(e.target.checked); },
|
||||
onCheckedChange: function (checked) { props.setIncludeArchived(checked === true); },
|
||||
}),
|
||||
tx(t, "showArchived", "Show archived"),
|
||||
),
|
||||
h("label", { className: "flex items-center gap-2 text-xs",
|
||||
title: "Group the Running column by assigned profile" },
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
checked: props.laneByProfile,
|
||||
onChange: function (e) { props.setLaneByProfile(e.target.checked); },
|
||||
onCheckedChange: function (checked) { props.setLaneByProfile(checked === true); },
|
||||
}),
|
||||
tx(t, "lanesByProfile", "Lanes by profile"),
|
||||
),
|
||||
|
|
@ -2122,10 +2135,9 @@
|
|||
}, tx(t, "apply", "Apply")),
|
||||
),
|
||||
h("label", { className: "hermes-kanban-bulk-reclaim-first", title: "Reclaim any active claims before reassigning" },
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
checked: reclaimFirst,
|
||||
onChange: function (e) { setReclaimFirst(e.target.checked); },
|
||||
onCheckedChange: function (checked) { setReclaimFirst(checked === true); },
|
||||
}),
|
||||
"Reclaim first",
|
||||
),
|
||||
|
|
@ -2313,14 +2325,12 @@
|
|||
},
|
||||
h("div", { className: "hermes-kanban-column-header",
|
||||
title: colHelp || "" },
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
className: "hermes-kanban-col-check",
|
||||
title: "Select all tasks in this column",
|
||||
"aria-label": `Select all tasks in ${colLabel || props.column.name}`,
|
||||
checked: props.column.tasks.length > 0 && props.column.tasks.every(function (t) { return props.selectedIds.has(t.id); }),
|
||||
onChange: function (e) {
|
||||
e.stopPropagation();
|
||||
onCheckedChange: function () {
|
||||
if (props.selectAllInColumn) props.selectAllInColumn(props.column.name);
|
||||
},
|
||||
onClick: function (e) { e.stopPropagation(); },
|
||||
|
|
@ -2461,8 +2471,7 @@
|
|||
if (props.toggleSelected) props.toggleSelected(t.id, false);
|
||||
}
|
||||
};
|
||||
const handleCheckbox = function (e) {
|
||||
e.stopPropagation();
|
||||
const handleCheckedChange = function () {
|
||||
props.toggleSelected(t.id, true);
|
||||
};
|
||||
|
||||
|
|
@ -2495,11 +2504,10 @@
|
|||
title: tx(i18n, "selectForBulk", "Select for bulk actions"),
|
||||
onClick: function (e) { e.stopPropagation(); },
|
||||
},
|
||||
h("input", {
|
||||
type: "checkbox",
|
||||
h(Checkbox, {
|
||||
className: "hermes-kanban-card-check",
|
||||
checked: props.selected,
|
||||
onChange: handleCheckbox,
|
||||
onCheckedChange: handleCheckedChange,
|
||||
onClick: function (e) { e.stopPropagation(); },
|
||||
"aria-label": `Select task ${t.id}`,
|
||||
}),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue