mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-09 15:58:34 +00:00
1b4e826e15
* fix(#3455): automated AI fix * fix: address Codex review on PR #3456 * fix: address Codex review on PR #3456 * fix: address Codex review on PR #3456 * fix: address Codex review on PR #3456 * fix: address Codex review on PR #3456 * fix: address Codex review on PR #3456 * fix: address Codex review on PR #3456 * fix(terminal): let explicit SFTP auto-open beat the saved layout A JumpServer SFTP deep link or host.autoOpenSftpPanel must still open file transfer when the saved default layout omitted SFTP. * fix(terminal): skip saved layout only when SFTP auto-open is available Telnet/plugin hosts can carry autoOpenSidePanel=sftp even though the protocol cannot serve SFTP. Those sessions should still get the saved default with the SFTP pane pruned. --------- Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com> Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
70 lines
2.4 KiB
TypeScript
70 lines
2.4 KiB
TypeScript
import { useCallback } from 'react';
|
|
|
|
import {
|
|
getFocusedSidePanelPane,
|
|
type SidePanelLayout,
|
|
type SidePanelTool,
|
|
} from '../../domain/sidePanelLayout';
|
|
import {
|
|
createWorkspaceLayoutPreset,
|
|
rekeySidePanelLayout,
|
|
withoutUnavailableSidePanelTools,
|
|
} from '../../domain/workspaceLayoutPreset';
|
|
import {
|
|
readWorkspaceLayoutPreset,
|
|
writeWorkspaceLayoutPreset,
|
|
} from './workspaceLayoutPresetStore';
|
|
|
|
/** Protocols whose sessions can actually serve an SFTP pane. */
|
|
function canServeSftp(protocol: string): boolean {
|
|
return protocol === 'local' || protocol === 'ssh' || protocol === 'mosh';
|
|
}
|
|
|
|
export type ResolvedWorkspaceLayoutPreset = {
|
|
layout: SidePanelLayout;
|
|
focusedTool: SidePanelTool;
|
|
/** Connection protocol used for availability filtering (`session.protocol ?? 'ssh'`). */
|
|
protocol: string;
|
|
};
|
|
|
|
/**
|
|
* Application boundary for the saved default workspace side panel layout.
|
|
* Owns the preset persistence lifecycle (read, validate, write) so UI
|
|
* components consume handlers instead of touching the store directly.
|
|
*/
|
|
export function useWorkspaceLayoutPresetState() {
|
|
/**
|
|
* Resolve the saved default preset into a fresh layout for a newly
|
|
* connected session. Panes the session cannot serve (SFTP on non-file
|
|
* protocols) are pruned, and ids are rekeyed so several workspaces can
|
|
* run the same preset in parallel. Returns null when there is no preset
|
|
* or nothing survives availability filtering.
|
|
*/
|
|
const resolveDefaultLayoutForSession = useCallback(
|
|
(session: { protocol?: string | null }): ResolvedWorkspaceLayoutPreset | null => {
|
|
const preset = readWorkspaceLayoutPreset();
|
|
if (!preset) return null;
|
|
|
|
const proto = session.protocol ?? 'ssh';
|
|
const usable = withoutUnavailableSidePanelTools(
|
|
preset.layout,
|
|
(tool) => tool !== 'sftp' || canServeSftp(proto),
|
|
);
|
|
if (!usable) return null;
|
|
|
|
const layout = rekeySidePanelLayout(usable, () => crypto.randomUUID());
|
|
return { layout, focusedTool: getFocusedSidePanelPane(layout).tool, protocol: proto };
|
|
},
|
|
[],
|
|
);
|
|
|
|
/** Validate and persist a live layout as the default. False when invalid or the write failed. */
|
|
const saveWorkspaceLayoutAsDefault = useCallback((layout: SidePanelLayout): boolean => {
|
|
const preset = createWorkspaceLayoutPreset(layout);
|
|
if (!preset) return false;
|
|
return writeWorkspaceLayoutPreset(preset);
|
|
}, []);
|
|
|
|
return { resolveDefaultLayoutForSession, saveWorkspaceLayoutAsDefault };
|
|
}
|