[Init] Initial commit - NetMesh terminal manager
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
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
This commit is contained in:
157
components/vault/useHostTreeInlineGroupActions.ts
Normal file
157
components/vault/useHostTreeInlineGroupActions.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { hostTreeInlineGroupDeleteStore } from '../../application/state/hostTreeInlineGroupDeleteStore';
|
||||
import { hostTreeInlineGroupEditStore } from '../../application/state/hostTreeInlineGroupEditStore';
|
||||
import { hostTreeInlineHostEditStore } from '../../application/state/hostTreeInlineHostEditStore';
|
||||
import {
|
||||
allocateUnnamedGroupPath,
|
||||
applyGroupPathRename,
|
||||
ensureAncestorPathsExpanded,
|
||||
groupDisplayName,
|
||||
} from '../../domain/hostGroupPathMutations';
|
||||
import type { Host, ManagedSource } from '../../types';
|
||||
import { toast } from '../ui/toast';
|
||||
|
||||
type UseHostTreeInlineGroupActionsParams = {
|
||||
customGroups: string[];
|
||||
hosts: Host[];
|
||||
managedSources: ManagedSource[];
|
||||
onUpdateCustomGroups: (groups: string[]) => void;
|
||||
onCommitGroupPathChange: (
|
||||
sourcePath: string,
|
||||
nextPath: string,
|
||||
) => Promise<
|
||||
| { ok: true }
|
||||
| { ok: false; error?: string; superseded?: true }
|
||||
>;
|
||||
selectedGroupPath: string | null;
|
||||
setSelectedGroupPath: (path: string | null) => void;
|
||||
ensurePathExpanded: (path: string) => void;
|
||||
unnamedGroupLabel: string;
|
||||
t: (key: string) => string;
|
||||
};
|
||||
|
||||
export function useHostTreeInlineGroupActions({
|
||||
customGroups,
|
||||
hosts,
|
||||
managedSources,
|
||||
onUpdateCustomGroups,
|
||||
onCommitGroupPathChange,
|
||||
selectedGroupPath,
|
||||
setSelectedGroupPath,
|
||||
ensurePathExpanded,
|
||||
unnamedGroupLabel,
|
||||
t,
|
||||
}: UseHostTreeInlineGroupActionsParams) {
|
||||
const startInlineNewGroup = useCallback((parentPath?: string) => {
|
||||
hostTreeInlineHostEditStore.clear();
|
||||
const parent = parentPath ?? null;
|
||||
const { name, path } = allocateUnnamedGroupPath(customGroups, parent, unnamedGroupLabel);
|
||||
onUpdateCustomGroups(Array.from(new Set([...customGroups, path])));
|
||||
if (parent) {
|
||||
ensureAncestorPathsExpanded(parent, ensurePathExpanded);
|
||||
ensurePathExpanded(parent);
|
||||
}
|
||||
hostTreeInlineGroupEditStore.startEdit({
|
||||
groupPath: path,
|
||||
initialName: name,
|
||||
isNew: true,
|
||||
});
|
||||
}, [customGroups, ensurePathExpanded, onUpdateCustomGroups, unnamedGroupLabel]);
|
||||
|
||||
const startInlineRenameGroup = useCallback((groupPath: string) => {
|
||||
hostTreeInlineHostEditStore.clear();
|
||||
hostTreeInlineGroupEditStore.startEdit({
|
||||
groupPath,
|
||||
initialName: groupDisplayName(groupPath),
|
||||
isNew: false,
|
||||
});
|
||||
}, []);
|
||||
|
||||
const cancelInlineGroupEdit = useCallback(() => {
|
||||
const edit = hostTreeInlineGroupEditStore.getEdit();
|
||||
if (!edit) return;
|
||||
if (edit.isNew) {
|
||||
onUpdateCustomGroups(customGroups.filter((groupPath) => groupPath !== edit.groupPath));
|
||||
}
|
||||
hostTreeInlineGroupEditStore.clear();
|
||||
}, [customGroups, onUpdateCustomGroups]);
|
||||
|
||||
const commitInlineGroupRename = useCallback(async (rawName: string): Promise<boolean> => {
|
||||
const edit = hostTreeInlineGroupEditStore.getEdit();
|
||||
if (!edit) return false;
|
||||
|
||||
const result = applyGroupPathRename({
|
||||
renameTargetPath: edit.groupPath,
|
||||
nextName: rawName,
|
||||
customGroups,
|
||||
hosts,
|
||||
managedSources,
|
||||
});
|
||||
|
||||
if (result.ok === false) {
|
||||
if (result.error === 'unchanged') {
|
||||
hostTreeInlineGroupEditStore.clear();
|
||||
return true;
|
||||
}
|
||||
if (result.error === 'required') {
|
||||
if (edit.isNew) {
|
||||
cancelInlineGroupEdit();
|
||||
return true;
|
||||
}
|
||||
toast.error(t('vault.groups.errors.required'));
|
||||
return false;
|
||||
}
|
||||
if (result.error === 'invalidChars') {
|
||||
toast.error(t('vault.groups.errors.invalidChars'));
|
||||
return false;
|
||||
}
|
||||
if (result.error === 'duplicatePath') {
|
||||
toast.error(t('vault.groups.errors.duplicatePath'));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const committed = await onCommitGroupPathChange(edit.groupPath, result.nextPath);
|
||||
if (!committed.ok) {
|
||||
toast.error(committed.error || t('common.error'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
selectedGroupPath
|
||||
&& (selectedGroupPath === edit.groupPath
|
||||
|| selectedGroupPath.startsWith(`${edit.groupPath}/`))
|
||||
) {
|
||||
const suffix = selectedGroupPath === edit.groupPath
|
||||
? ''
|
||||
: selectedGroupPath.slice(edit.groupPath.length);
|
||||
setSelectedGroupPath(result.nextPath + suffix);
|
||||
}
|
||||
|
||||
hostTreeInlineGroupEditStore.clear();
|
||||
return true;
|
||||
}, [
|
||||
cancelInlineGroupEdit,
|
||||
customGroups,
|
||||
hosts,
|
||||
managedSources,
|
||||
onCommitGroupPathChange,
|
||||
selectedGroupPath,
|
||||
setSelectedGroupPath,
|
||||
t,
|
||||
]);
|
||||
|
||||
const startInlineDeleteGroup = useCallback((groupPath: string) => {
|
||||
hostTreeInlineGroupDeleteStore.open(groupPath);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
startInlineNewGroup,
|
||||
startInlineRenameGroup,
|
||||
commitInlineGroupRename,
|
||||
cancelInlineGroupEdit,
|
||||
startInlineDeleteGroup,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user