mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-03 02:11:48 +00:00
fix: replace all buttons for design system buttons
This commit is contained in:
parent
529eb29b6a
commit
e116957a63
15 changed files with 117 additions and 193 deletions
|
|
@ -10,9 +10,9 @@ import {
|
|||
import { api } from "@/lib/api";
|
||||
import type { AnalyticsResponse, AnalyticsDailyEntry, AnalyticsModelEntry, AnalyticsSkillEntry } from "@/lib/api";
|
||||
import { timeAgo } from "@/lib/utils";
|
||||
import { Button } from "@nous-research/ui";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { usePageHeader } from "@/contexts/usePageHeader";
|
||||
import { useI18n } from "@/i18n";
|
||||
import { PluginSlot } from "@/plugins";
|
||||
|
|
@ -317,9 +317,7 @@ export default function AnalyticsPage() {
|
|||
<Button
|
||||
key={p.label}
|
||||
type="button"
|
||||
variant={days === p.days ? "default" : "outline"}
|
||||
size="sm"
|
||||
className="h-7 min-w-0 text-xs"
|
||||
outlined={days !== p.days}
|
||||
onClick={() => setDays(p.days)}
|
||||
>
|
||||
{p.label}
|
||||
|
|
@ -328,13 +326,11 @@ export default function AnalyticsPage() {
|
|||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
outlined
|
||||
onClick={load}
|
||||
disabled={loading}
|
||||
className="h-7 text-xs"
|
||||
prefix={<RefreshCw />}
|
||||
>
|
||||
<RefreshCw className="mr-1 h-3 w-3" />
|
||||
{t.common.refresh}
|
||||
</Button>
|
||||
</div>,
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import { getNestedValue, setNestedValue } from "@/lib/nested";
|
|||
import { useToast } from "@/hooks/useToast";
|
||||
import { Toast } from "@/components/Toast";
|
||||
import { AutoField } from "@/components/AutoField";
|
||||
import { Button } from "@nous-research/ui";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
|
@ -345,10 +345,10 @@ export default function ConfigPage() {
|
|||
</code>
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Button variant="ghost" size="sm" onClick={handleExport} title={t.config.exportConfig} aria-label={t.config.exportConfig}>
|
||||
<Button outlined onClick={handleExport} title={t.config.exportConfig} aria-label={t.config.exportConfig} className="!p-2 aspect-square">
|
||||
<Download className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" onClick={() => fileInputRef.current?.click()} title={t.config.importConfig} aria-label={t.config.importConfig}>
|
||||
<Button outlined onClick={() => fileInputRef.current?.click()} title={t.config.importConfig} aria-label={t.config.importConfig} className="!p-2 aspect-square">
|
||||
<Upload className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<input ref={fileInputRef} type="file" accept=".json" className="hidden" onChange={handleImport} />
|
||||
|
|
@ -358,7 +358,7 @@ export default function ConfigPage() {
|
|||
: prettyCategoryName(activeCategory);
|
||||
const resetTitle = t.config.resetScopeTooltip.replace("{scope}", resetScopeLabel);
|
||||
return (
|
||||
<Button variant="ghost" size="sm" onClick={handleReset} title={resetTitle} aria-label={resetTitle}>
|
||||
<Button outlined onClick={handleReset} title={resetTitle} aria-label={resetTitle} className="!p-2 aspect-square">
|
||||
<RotateCcw className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
);
|
||||
|
|
@ -367,32 +367,19 @@ export default function ConfigPage() {
|
|||
<div className="w-px h-5 bg-border mx-1" />
|
||||
|
||||
<Button
|
||||
variant={yamlMode ? "default" : "outline"}
|
||||
size="sm"
|
||||
outlined={!yamlMode}
|
||||
onClick={() => setYamlMode(!yamlMode)}
|
||||
className="gap-1.5"
|
||||
prefix={yamlMode ? <FormInput /> : <Code />}
|
||||
>
|
||||
{yamlMode ? (
|
||||
<>
|
||||
<FormInput className="h-3.5 w-3.5" />
|
||||
{t.common.form}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Code className="h-3.5 w-3.5" />
|
||||
YAML
|
||||
</>
|
||||
)}
|
||||
{yamlMode ? t.common.form : "YAML"}
|
||||
</Button>
|
||||
|
||||
{yamlMode ? (
|
||||
<Button size="sm" onClick={handleYamlSave} disabled={yamlSaving} className="gap-1.5">
|
||||
<Save className="h-3.5 w-3.5" />
|
||||
<Button onClick={handleYamlSave} disabled={yamlSaving} prefix={<Save />}>
|
||||
{yamlSaving ? t.common.saving : t.common.save}
|
||||
</Button>
|
||||
) : (
|
||||
<Button size="sm" onClick={handleSave} disabled={saving} className="gap-1.5">
|
||||
<Save className="h-3.5 w-3.5" />
|
||||
<Button onClick={handleSave} disabled={saving} prefix={<Save />}>
|
||||
{saving ? t.common.saving : t.common.save}
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Clock, Pause, Play, Plus, Trash2, Zap } from "lucide-react";
|
||||
import { H2 } from "@nous-research/ui";
|
||||
import { Button, H2 } from "@nous-research/ui";
|
||||
import { api } from "@/lib/api";
|
||||
import type { CronJob } from "@/lib/api";
|
||||
import { DeleteConfirmDialog } from "@/components/DeleteConfirmDialog";
|
||||
|
|
@ -9,7 +9,6 @@ import { useConfirmDelete } from "@/hooks/useConfirmDelete";
|
|||
import { Toast } from "@/components/Toast";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Select, SelectOption } from "@/components/ui/select";
|
||||
|
|
@ -166,7 +165,6 @@ export default function CronPage() {
|
|||
loading={jobDelete.isDeleting}
|
||||
/>
|
||||
|
||||
{/* Create new job form */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-base">
|
||||
|
|
@ -237,9 +235,9 @@ export default function CronPage() {
|
|||
<Button
|
||||
onClick={handleCreate}
|
||||
disabled={creating}
|
||||
prefix={<Plus />}
|
||||
className="w-full"
|
||||
>
|
||||
<Plus className="h-3 w-3" />
|
||||
{creating ? t.common.creating : t.common.create}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -248,7 +246,6 @@ export default function CronPage() {
|
|||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Jobs list */}
|
||||
<div className="flex flex-col gap-3">
|
||||
<H2
|
||||
variant="sm"
|
||||
|
|
@ -269,7 +266,6 @@ export default function CronPage() {
|
|||
{jobs.map((job) => (
|
||||
<Card key={job.id}>
|
||||
<CardContent className="flex items-center gap-4 py-4">
|
||||
{/* Info */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<span className="font-medium text-sm truncate">
|
||||
|
|
@ -306,16 +302,15 @@ export default function CronPage() {
|
|||
)}
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex items-center gap-1 shrink-0">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
outlined
|
||||
title={job.state === "paused" ? t.cron.resume : t.cron.pause}
|
||||
aria-label={
|
||||
job.state === "paused" ? t.cron.resume : t.cron.pause
|
||||
}
|
||||
onClick={() => handlePauseResume(job)}
|
||||
className="!p-2 aspect-square"
|
||||
>
|
||||
{job.state === "paused" ? (
|
||||
<Play className="h-4 w-4 text-success" />
|
||||
|
|
@ -325,21 +320,21 @@ export default function CronPage() {
|
|||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
outlined
|
||||
title={t.cron.triggerNow}
|
||||
aria-label={t.cron.triggerNow}
|
||||
onClick={() => handleTrigger(job)}
|
||||
className="!p-2 aspect-square"
|
||||
>
|
||||
<Zap className="h-4 w-4" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
outlined
|
||||
title={t.common.delete}
|
||||
aria-label={t.common.delete}
|
||||
onClick={() => jobDelete.requestDelete(job.id)}
|
||||
className="!p-2 aspect-square"
|
||||
>
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
</Button>
|
||||
|
|
@ -348,6 +343,7 @@ export default function CronPage() {
|
|||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<PluginSlot name="cron:bottom" />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,19 @@ import { useLayoutEffect } from "react";
|
|||
import { ExternalLink } from "lucide-react";
|
||||
import { useI18n } from "@/i18n";
|
||||
import { usePageHeader } from "@/contexts/usePageHeader";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { PluginSlot } from "@/plugins";
|
||||
|
||||
export const HERMES_DOCS_URL = "https://hermes-agent.nousresearch.com/docs/";
|
||||
|
||||
const DS_BUTTON_OUTLINED_LINK_CN = cn(
|
||||
"group relative inline-grid grid-cols-[auto_1fr_auto] items-center",
|
||||
"px-[.9em_.75em] py-[1.25em] gap-2",
|
||||
"leading-0 font-bold tracking-[0.2em] uppercase",
|
||||
"text-midground bg-transparent shadow-midground",
|
||||
"shadow-[inset_-1px_-1px_0_0_#00000080,inset_1px_1px_0_0_#ffffff80]",
|
||||
);
|
||||
|
||||
export default function DocsPage() {
|
||||
const { t } = useI18n();
|
||||
const { setEnd } = usePageHeader();
|
||||
|
|
@ -18,12 +25,9 @@ export default function DocsPage() {
|
|||
href={HERMES_DOCS_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={cn(
|
||||
buttonVariants({ variant: "outline", size: "sm" }),
|
||||
"h-7 text-xs",
|
||||
)}
|
||||
className={DS_BUTTON_OUTLINED_LINK_CN}
|
||||
>
|
||||
<ExternalLink className="mr-1.5 h-3 w-3" />
|
||||
<ExternalLink className="size-3.5" />
|
||||
{t.app.openDocumentation}
|
||||
</a>,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import { Toast } from "@/components/Toast";
|
|||
import { useConfirmDelete } from "@/hooks/useConfirmDelete";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { OAuthProvidersCard } from "@/components/OAuthProvidersCard";
|
||||
import { Button } from "@nous-research/ui";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
|
@ -134,9 +134,8 @@ function EnvVarRow({
|
|||
{t.env.getKey} <ExternalLink className="h-2.5 w-2.5" />
|
||||
</a>
|
||||
)}
|
||||
<Button size="sm" variant="outline" className="h-6 text-[0.6rem] px-2"
|
||||
<Button outlined prefix={<Pencil />}
|
||||
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}>
|
||||
<Pencil className="h-2.5 w-2.5" />
|
||||
{t.common.set}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -159,9 +158,8 @@ function EnvVarRow({
|
|||
{t.env.getKey} <ExternalLink className="h-2.5 w-2.5" />
|
||||
</a>
|
||||
)}
|
||||
<Button size="sm" variant="outline" className="h-7 text-[0.6rem]"
|
||||
<Button outlined prefix={<Pencil />}
|
||||
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}>
|
||||
<Pencil className="h-3 w-3" />
|
||||
{t.common.set}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -206,26 +204,25 @@ function EnvVarRow({
|
|||
</div>
|
||||
|
||||
{info.is_set && (
|
||||
<Button size="sm" variant="ghost" onClick={() => onReveal(varKey)}
|
||||
<Button outlined onClick={() => onReveal(varKey)}
|
||||
title={isRevealed ? t.env.hideValue : t.env.showValue}
|
||||
aria-label={isRevealed ? `Hide ${varKey}` : `Reveal ${varKey}`}>
|
||||
aria-label={isRevealed ? `Hide ${varKey}` : `Reveal ${varKey}`}
|
||||
className="!p-2 aspect-square">
|
||||
{isRevealed
|
||||
? <EyeOff className="h-4 w-4" />
|
||||
: <Eye className="h-4 w-4" />}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Button size="sm" variant="outline"
|
||||
<Button outlined prefix={<Pencil />}
|
||||
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}>
|
||||
<Pencil className="h-3 w-3" />
|
||||
{info.is_set ? t.common.replace : t.common.set}
|
||||
</Button>
|
||||
|
||||
{info.is_set && (
|
||||
<Button size="sm" variant="ghost"
|
||||
className="text-destructive hover:text-destructive hover:bg-destructive/10"
|
||||
<Button outlined prefix={<Trash2 />}
|
||||
className="text-destructive hover:!text-destructive"
|
||||
onClick={() => onClear(varKey)} disabled={saving === varKey || clearDialogOpen}>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
{saving === varKey ? "..." : t.common.clear}
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -238,13 +235,12 @@ function EnvVarRow({
|
|||
onChange={(e) => setEdits((prev) => ({ ...prev, [varKey]: e.target.value }))}
|
||||
placeholder={info.is_set ? t.env.replaceCurrentValue.replace("{preview}", info.redacted_value ?? "---") : t.env.enterValue}
|
||||
className="flex-1 font-mono-ui text-xs" />
|
||||
<Button size="sm" onClick={() => onSave(varKey)}
|
||||
<Button onClick={() => onSave(varKey)} prefix={<Save />}
|
||||
disabled={saving === varKey || !edits[varKey]}>
|
||||
<Save className="h-3 w-3" />
|
||||
{saving === varKey ? "..." : t.common.save}
|
||||
</Button>
|
||||
<Button size="sm" variant="ghost" onClick={() => onCancelEdit(varKey)}>
|
||||
<X className="h-3 w-3" /> {t.common.cancel}
|
||||
<Button outlined prefix={<X />} onClick={() => onCancelEdit(varKey)}>
|
||||
{t.common.cancel}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -537,7 +533,7 @@ export default function EnvPage() {
|
|||
{t.env.changesNote}
|
||||
</p>
|
||||
</div>
|
||||
<Button variant="ghost" size="sm" onClick={() => setShowAdvanced(!showAdvanced)}>
|
||||
<Button outlined onClick={() => setShowAdvanced(!showAdvanced)}>
|
||||
{showAdvanced ? t.env.hideAdvanced : t.env.showAdvanced}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useEffect, useLayoutEffect, useState, useCallback, useRef } from "react";
|
||||
import { FileText, RefreshCw } from "lucide-react";
|
||||
import { api } from "@/lib/api";
|
||||
import { Button } from "@nous-research/ui";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
|
@ -101,13 +101,11 @@ export default function LogsPage() {
|
|||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
outlined
|
||||
onClick={fetchLogs}
|
||||
disabled={loading}
|
||||
className="h-7 text-xs"
|
||||
prefix={<RefreshCw />}
|
||||
>
|
||||
<RefreshCw className="mr-1 h-3 w-3" />
|
||||
{t.common.refresh}
|
||||
</Button>
|
||||
</div>,
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ import { timeAgo } from "@/lib/utils";
|
|||
import { Markdown } from "@/components/Markdown";
|
||||
import { PlatformsCard } from "@/components/PlatformsCard";
|
||||
import { Toast } from "@/components/Toast";
|
||||
import { Button } from "@nous-research/ui";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { DeleteConfirmDialog } from "@/components/DeleteConfirmDialog";
|
||||
import { useConfirmDelete } from "@/hooks/useConfirmDelete";
|
||||
|
|
@ -356,9 +356,8 @@ function SessionRow({
|
|||
</Badge>
|
||||
{resumeInChatEnabled && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 text-muted-foreground hover:text-success"
|
||||
outlined
|
||||
className="!p-1.5 aspect-square text-muted-foreground hover:text-success"
|
||||
aria-label={t.sessions.resumeInChat}
|
||||
title={t.sessions.resumeInChat}
|
||||
onClick={(e) => {
|
||||
|
|
@ -370,9 +369,8 @@ function SessionRow({
|
|||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 text-muted-foreground hover:text-destructive"
|
||||
outlined
|
||||
className="!p-1.5 aspect-square text-muted-foreground hover:text-destructive"
|
||||
aria-label={t.sessions.deleteSession}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
|
@ -808,9 +806,8 @@ export default function SessionsPage() {
|
|||
</span>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-7 w-7 p-0"
|
||||
outlined
|
||||
className="!p-1.5 aspect-square"
|
||||
disabled={page === 0}
|
||||
onClick={() => setPage((p) => p - 1)}
|
||||
aria-label={t.sessions.previousPage}
|
||||
|
|
@ -822,9 +819,8 @@ export default function SessionsPage() {
|
|||
{Math.ceil(total / PAGE_SIZE)}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-7 w-7 p-0"
|
||||
outlined
|
||||
className="!p-1.5 aspect-square"
|
||||
disabled={(page + 1) * PAGE_SIZE >= total}
|
||||
onClick={() => setPage((p) => p + 1)}
|
||||
aria-label={t.sessions.nextPage}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue