Files
NetMesh/components/ui/sort-dropdown.tsx
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

59 lines
2.9 KiB
TypeScript

import { Calendar,CalendarClock,Check,ChevronDown,ChevronUp,FolderTree,GripVertical,SortAsc,SortDesc } from 'lucide-react';
import React from 'react';
import { useI18n } from "../../application/i18n/I18nProvider";
import { Button } from './button';
import { Dropdown,DropdownContent,DropdownTrigger } from './dropdown';
export type SortMode = 'manual' | 'az' | 'za' | 'newest' | 'oldest' | 'group';
const SORT_OPTIONS: Record<SortMode, { labelKey: string; icon: React.ReactElement; triggerIcon: React.ReactElement }> = {
manual: { labelKey: 'sort.manual', icon: <GripVertical className="w-4 h-4 shrink-0" />, triggerIcon: <GripVertical className="w-4 h-4" /> },
az: { labelKey: 'sort.az', icon: <SortAsc className="w-4 h-4 shrink-0" />, triggerIcon: <SortAsc className="w-4 h-4" /> },
za: { labelKey: 'sort.za', icon: <SortDesc className="w-4 h-4 shrink-0" />, triggerIcon: <SortDesc className="w-4 h-4" /> },
newest: { labelKey: 'sort.newest', icon: <Calendar className="w-4 h-4 shrink-0" />, triggerIcon: <Calendar className="w-4 h-4" /> },
oldest: { labelKey: 'sort.oldest', icon: <CalendarClock className="w-4 h-4 shrink-0" />, triggerIcon: <CalendarClock className="w-4 h-4" /> },
group: { labelKey: 'sort.group', icon: <FolderTree className="w-4 h-4 shrink-0" />, triggerIcon: <FolderTree className="w-4 h-4" /> },
};
interface SortDropdownProps {
value: SortMode;
onChange: (mode: SortMode) => void;
className?: string;
modes?: SortMode[];
}
export const SortDropdown: React.FC<SortDropdownProps> = ({ value, onChange, className, modes }) => {
const [open, setOpen] = React.useState(false);
const { t } = useI18n();
const visibleModes = modes ?? (Object.keys(SORT_OPTIONS) as SortMode[]);
return (
<Dropdown open={open} onOpenChange={setOpen}>
<DropdownTrigger asChild>
<Button variant="ghost" size="icon" className={className || "h-8 w-8"}>
{SORT_OPTIONS[value].triggerIcon}
{open ? <ChevronUp size={10} className="ml-0.5" /> : <ChevronDown size={10} className="ml-0.5" />}
</Button>
</DropdownTrigger>
<DropdownContent className="w-44" align="end">
{visibleModes.map(mode => (
<Button
key={mode}
variant={value === mode ? 'secondary' : 'ghost'}
className="w-full justify-start gap-2 h-9"
onClick={() => {
onChange(mode);
setOpen(false);
}}
>
{SORT_OPTIONS[mode].icon} {t(SORT_OPTIONS[mode].labelKey)}
{value === mode && <Check size={12} className="ml-auto" />}
</Button>
))}
</DropdownContent>
</Dropdown>
);
};
export default SortDropdown;