Files
NetMesh/components/host-details/CreateGroupPanel.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

128 lines
4.7 KiB
TypeScript

/**
* Create Group Sub-Panel
* Panel for creating new groups within the host details
*/
import { FolderPlus,HelpCircle,Plus } from 'lucide-react';
import React from 'react';
import { useI18n } from '../../application/i18n/I18nProvider';
import { AsidePanel,AsidePanelContent,type AsidePanelLayout,type AsidePanelResizeProps } from '../ui/aside-panel';
import { Button } from '../ui/button';
import { Card } from '../ui/card';
import { Input } from '../ui/input';
interface ToggleRowProps {
label: string;
enabled: boolean;
onToggle: () => void;
}
const ToggleRow: React.FC<ToggleRowProps> = ({ label, enabled, onToggle }) => (
<div className="flex items-center justify-between">
<span className="text-sm">{label}</span>
<button
type="button"
onClick={onToggle}
className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors ${enabled ? 'bg-primary' : 'bg-muted'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${enabled ? 'translate-x-4' : 'translate-x-1'
}`}
/>
</button>
</div>
);
export interface CreateGroupPanelProps {
newGroupName: string;
setNewGroupName: (name: string) => void;
newGroupParent: string;
setNewGroupParent: (parent: string) => void;
groups: string[];
onSave: () => void;
onBack: () => void;
onCancel: () => void;
layout?: AsidePanelLayout;
}
export type CreateGroupPanelPropsWithResize = CreateGroupPanelProps & AsidePanelResizeProps;
export const CreateGroupPanel: React.FC<CreateGroupPanelPropsWithResize> = ({
newGroupName,
setNewGroupName,
newGroupParent,
setNewGroupParent,
groups,
onSave,
onBack,
onCancel,
layout = 'overlay',
resizable,
persistWidthStorageKey,
resizeAriaLabel,
}) => {
const { t } = useI18n();
return (
<AsidePanel
open={true}
onClose={onCancel}
title={t('hostDetails.group.title')}
showBackButton={true}
onBack={onBack}
layout={layout}
resizable={resizable}
persistWidthStorageKey={persistWidthStorageKey}
resizeAriaLabel={resizeAriaLabel}
actions={
<Button size="sm" onClick={onSave} disabled={!newGroupName.trim()}>
{t('common.save')}
</Button>
}
>
<AsidePanelContent>
<Card className="p-3 space-y-3 bg-card border-border/80">
<p className="text-xs font-semibold">{t('hostDetails.group.general')}</p>
<div className="flex items-center gap-2">
<div className="h-10 w-10 rounded-lg bg-primary/15 flex items-center justify-center">
<FolderPlus size={18} className="text-primary" />
</div>
<Input
placeholder={t('hostDetails.group.namePlaceholder')}
value={newGroupName}
onChange={(e) => setNewGroupName(e.target.value)}
className="h-10 flex-1"
autoFocus
/>
</div>
<div className="relative">
<Input
placeholder={t('hostDetails.group.parentPlaceholder')}
value={newGroupParent}
onChange={(e) => setNewGroupParent(e.target.value)}
list="parent-group-options"
className="h-10"
/>
<datalist id="parent-group-options">
{groups.map((g) => <option key={g} value={g} />)}
</datalist>
</div>
</Card>
<Card className="p-3 space-y-2 bg-card border-border/80">
<div className="flex items-center justify-between">
<p className="text-xs font-semibold">{t('hostDetails.group.cloudSync')}</p>
<HelpCircle size={14} className="text-muted-foreground" />
</div>
<ToggleRow label={t('hostDetails.group.cloudSync')} enabled={false} onToggle={() => { }} />
</Card>
<Button variant="ghost" className="w-full h-10 gap-2">
<Plus size={16} /> {t('hostDetails.group.addProtocol')}
</Button>
</AsidePanelContent>
</AsidePanel>
);
};
export default CreateGroupPanel;