@lemoncat7/dsh-ssh 1.5.3 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +10 -0
- package/README.md +22 -1
- package/docs/releases/1.6.0.md +12 -0
- package/docs/releases/1.7.0.md +11 -0
- package/lib/activity-panel.d.ts.map +1 -1
- package/lib/activity-panel.js +14 -8
- package/lib/activity-panel.js.map +1 -1
- package/lib/adaptive-workspace.d.ts.map +1 -1
- package/lib/adaptive-workspace.js +5 -2
- package/lib/adaptive-workspace.js.map +1 -1
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +24 -2
- package/lib/api.js.map +1 -1
- package/lib/client-api.d.ts +21 -6
- package/lib/client-api.d.ts.map +1 -1
- package/lib/client-api.js +21 -12
- package/lib/client-api.js.map +1 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +360 -69
- package/lib/client.js.map +4 -4
- package/lib/commands-panel.d.ts.map +1 -1
- package/lib/commands-panel.js +11 -7
- package/lib/commands-panel.js.map +1 -1
- package/lib/docked-panel-compat.d.ts +1 -1
- package/lib/docked-panel-compat.d.ts.map +1 -1
- package/lib/docked-panel-compat.js +3 -2
- package/lib/docked-panel-compat.js.map +1 -1
- package/lib/file-entry-delete-dialog.d.ts.map +1 -1
- package/lib/file-entry-delete-dialog.js +5 -2
- package/lib/file-entry-delete-dialog.js.map +1 -1
- package/lib/file-transfer-workspace.d.ts.map +1 -1
- package/lib/file-transfer-workspace.js +48 -30
- package/lib/file-transfer-workspace.js.map +1 -1
- package/lib/ftp-profile-editor.d.ts.map +1 -1
- package/lib/ftp-profile-editor.js +13 -8
- package/lib/ftp-profile-editor.js.map +1 -1
- package/lib/html-file-preview.d.ts +8 -0
- package/lib/html-file-preview.d.ts.map +1 -0
- package/lib/html-file-preview.js +58 -0
- package/lib/html-file-preview.js.map +1 -0
- package/lib/i18n.d.ts +17 -0
- package/lib/i18n.d.ts.map +1 -0
- package/lib/i18n.js +36 -0
- package/lib/i18n.js.map +1 -0
- package/lib/local-markdown-file.d.ts +5 -0
- package/lib/local-markdown-file.d.ts.map +1 -0
- package/lib/local-markdown-file.js +63 -0
- package/lib/local-markdown-file.js.map +1 -0
- package/lib/local-workspace.d.ts +1 -0
- package/lib/local-workspace.d.ts.map +1 -1
- package/lib/local-workspace.js +3 -2
- package/lib/local-workspace.js.map +1 -1
- package/lib/locales/messages.d.ts +2702 -0
- package/lib/locales/messages.d.ts.map +1 -0
- package/lib/locales/messages.js +2683 -0
- package/lib/locales/messages.js.map +1 -0
- package/lib/markdown-file.d.ts +19 -0
- package/lib/markdown-file.d.ts.map +1 -0
- package/lib/markdown-file.js +52 -0
- package/lib/markdown-file.js.map +1 -0
- package/lib/markdown-preview-editor.d.ts +8 -0
- package/lib/markdown-preview-editor.d.ts.map +1 -0
- package/lib/markdown-preview-editor.js +62 -0
- package/lib/markdown-preview-editor.js.map +1 -0
- package/lib/native-directory-button.d.ts.map +1 -1
- package/lib/native-directory-button.js +6 -3
- package/lib/native-directory-button.js.map +1 -1
- package/lib/preview-refresh-control.d.ts +9 -0
- package/lib/preview-refresh-control.d.ts.map +1 -0
- package/lib/preview-refresh-control.js +9 -0
- package/lib/preview-refresh-control.js.map +1 -0
- package/lib/profile-editor.d.ts.map +1 -1
- package/lib/profile-editor.js +13 -8
- package/lib/profile-editor.js.map +1 -1
- package/lib/project-session-dialog.d.ts.map +1 -1
- package/lib/project-session-dialog.js +7 -4
- package/lib/project-session-dialog.js.map +1 -1
- package/lib/remote-path-input.d.ts.map +1 -1
- package/lib/remote-path-input.js +10 -7
- package/lib/remote-path-input.js.map +1 -1
- package/lib/remote-workspace-tree.d.ts.map +1 -1
- package/lib/remote-workspace-tree.js +16 -11
- package/lib/remote-workspace-tree.js.map +1 -1
- package/lib/resizable-split.d.ts.map +1 -1
- package/lib/resizable-split.js +4 -1
- package/lib/resizable-split.js.map +1 -1
- package/lib/sftp-client.d.ts +13 -2
- package/lib/sftp-client.d.ts.map +1 -1
- package/lib/sftp-client.js +101 -48
- package/lib/sftp-client.js.map +1 -1
- package/lib/sftp-markdown-file.d.ts +6 -0
- package/lib/sftp-markdown-file.d.ts.map +1 -0
- package/lib/sftp-markdown-file.js +72 -0
- package/lib/sftp-markdown-file.js.map +1 -0
- package/lib/sftp.d.ts +1 -0
- package/lib/sftp.d.ts.map +1 -1
- package/lib/sftp.js +3 -1
- package/lib/sftp.js.map +1 -1
- package/lib/ssh-locale-binding.d.ts +9 -0
- package/lib/ssh-locale-binding.d.ts.map +1 -0
- package/lib/ssh-locale-binding.js +29 -0
- package/lib/ssh-locale-binding.js.map +1 -0
- package/lib/terminal-bootstrap-echo.d.ts +15 -0
- package/lib/terminal-bootstrap-echo.d.ts.map +1 -0
- package/lib/terminal-bootstrap-echo.js +62 -0
- package/lib/terminal-bootstrap-echo.js.map +1 -0
- package/lib/terminal-directory.d.ts +3 -0
- package/lib/terminal-directory.d.ts.map +1 -0
- package/lib/terminal-directory.js +28 -0
- package/lib/terminal-directory.js.map +1 -0
- package/lib/terminal-session.d.ts +2 -1
- package/lib/terminal-session.d.ts.map +1 -1
- package/lib/terminal-session.js +22 -7
- package/lib/terminal-session.js.map +1 -1
- package/lib/terminal-shell-integration.d.ts +6 -0
- package/lib/terminal-shell-integration.d.ts.map +1 -0
- package/lib/terminal-shell-integration.js +53 -0
- package/lib/terminal-shell-integration.js.map +1 -0
- package/lib/terminal-workspace.d.ts +2 -1
- package/lib/terminal-workspace.d.ts.map +1 -1
- package/lib/terminal-workspace.js +10 -5
- package/lib/terminal-workspace.js.map +1 -1
- package/lib/terminal.d.ts +4 -0
- package/lib/terminal.d.ts.map +1 -1
- package/lib/terminal.js +31 -1
- package/lib/terminal.js.map +1 -1
- package/lib/ui-components.d.ts.map +1 -1
- package/lib/ui-components.js +14 -8
- package/lib/ui-components.js.map +1 -1
- package/lib/use-file-preview.d.ts +13 -0
- package/lib/use-file-preview.d.ts.map +1 -0
- package/lib/use-file-preview.js +101 -0
- package/lib/use-file-preview.js.map +1 -0
- package/lib/use-markdown-draft.d.ts +23 -0
- package/lib/use-markdown-draft.d.ts.map +1 -0
- package/lib/use-markdown-draft.js +115 -0
- package/lib/use-markdown-draft.js.map +1 -0
- package/lib/use-ssh-locale.d.ts +4 -0
- package/lib/use-ssh-locale.d.ts.map +1 -0
- package/lib/use-ssh-locale.js +7 -0
- package/lib/use-ssh-locale.js.map +1 -0
- package/package.json +10 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-panel.d.ts","sourceRoot":"","sources":["../src/commands-panel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commands-panel.d.ts","sourceRoot":"","sources":["../src/commands-panel.tsx"],"names":[],"mappings":"AAQA,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAyC/G"}
|
package/lib/commands-panel.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useSshLocale } from './use-ssh-locale.js';
|
|
3
|
+
import { t } from './i18n.js';
|
|
2
4
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
5
|
import { IconEditOutline16, IconPlusOutline16, IconTrashOutline16 } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
6
|
import { api } from './client-api.js';
|
|
5
7
|
import { Dialog, Field, errorMessage } from './ui-components.js';
|
|
6
8
|
export function CommandsPanel({ onChoose }) {
|
|
9
|
+
const sshLocale = useSshLocale();
|
|
7
10
|
const [items, setItems] = useState([]);
|
|
8
11
|
const [query, setQuery] = useState('');
|
|
9
12
|
const [page, setPage] = useState(0);
|
|
@@ -25,30 +28,31 @@ export function CommandsPanel({ onChoose }) {
|
|
|
25
28
|
}
|
|
26
29
|
}, []);
|
|
27
30
|
useEffect(() => { void refresh(); }, [refresh]);
|
|
28
|
-
const searchIndex = useMemo(() => items.map(item => ({ item, text: `${item.name}\n${item.command}`.toLocaleLowerCase() })), [items]);
|
|
31
|
+
const searchIndex = useMemo(() => items.map(item => ({ item, text: `${item.name}\n${item.command}`.toLocaleLowerCase() })), [items, sshLocale]);
|
|
29
32
|
const filtered = useMemo(() => {
|
|
30
33
|
const needle = query.toLocaleLowerCase();
|
|
31
34
|
return searchIndex.filter(entry => entry.text.includes(needle)).map(entry => entry.item);
|
|
32
|
-
}, [searchIndex, query]);
|
|
35
|
+
}, [searchIndex, query, sshLocale]);
|
|
33
36
|
const currentPage = Math.min(page, Math.max(0, Math.ceil(filtered.length / 50) - 1));
|
|
34
37
|
const visible = filtered.slice(currentPage * 50, (currentPage + 1) * 50);
|
|
35
|
-
return _jsxs("div", { className: onChoose ? 'dsh-ssh-command-picker' : 'dsh-ssh-commands-pane', children: [!onChoose && _jsxs("header", { className: "dsh-ssh-content-heading", children: [_jsxs("div", { children: [_jsx("h1", { children: "
|
|
36
|
-
setDeleting(undefined); }, children: [_jsx("p", { children: "
|
|
38
|
+
return _jsxs("div", { className: onChoose ? 'dsh-ssh-command-picker' : 'dsh-ssh-commands-pane', children: [!onChoose && _jsxs("header", { className: "dsh-ssh-content-heading", children: [_jsxs("div", { children: [_jsx("h1", { children: t("client.savedCommands") }), _jsx("p", { children: t("commands-panel.saveCommandsManuallyThenSelectAndConfirmExecutionIn") })] }), _jsxs("button", { type: "button", className: "dsh-ssh-primary-button", onClick: () => setEditing('new'), children: [_jsx(IconPlusOutline16, { size: 16 }), t("commands-panel.newCommand")] })] }), _jsxs("label", { className: "dsh-ssh-search", children: [_jsx("span", { className: "sr-only", children: t("commands-panel.searchCommands") }), _jsx("input", { value: query, onChange: event => { setQuery(event.target.value); setPage(0); }, placeholder: t("commands-panel.searchNamesOrCommands") })] }), error && _jsxs("p", { className: "dsh-ssh-inline-error", role: "alert", children: [error, _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", onClick: () => { void refresh(); }, children: t("commands-panel.retry") })] }), _jsx("div", { className: "dsh-ssh-command-list dsh-ssh-scroll-surface", children: loading ? _jsx("p", { role: "status", children: t("commands-panel.loadingCommands") }) : filtered.length === 0 ? _jsx("p", { className: "dsh-ssh-command-empty", children: query ? t("commands-panel.noMatchingCommands") : onChoose ? t("commands-panel.noSavedCommandsYetCreateOneOnTheWorkspace") : t("commands-panel.noSavedCommandsYetClickNewCommandToGet") }) : visible.map(item => _jsxs("article", { "data-ssh-interactive": "row", className: "dsh-ssh-command-row", children: [_jsxs("div", { children: [_jsx("strong", { children: item.name }), _jsx("pre", { children: item.command })] }), _jsxs("div", { className: "dsh-ssh-heading-actions", children: [onChoose && _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", onClick: () => onChoose(item.command), children: t("commands-panel.select") }), !onChoose && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "dsh-ssh-icon-button", title: t("commands-panel.editCommand"), "aria-label": t("client.edit2", [item.name]), onClick: () => setEditing(item), children: _jsx(IconEditOutline16, { size: 16 }) }), _jsx("button", { type: "button", className: "dsh-ssh-icon-button is-danger", title: t("commands-panel.deleteCommand"), "aria-label": t("client.delete2", [item.name]), onClick: () => setDeleting(item), children: _jsx(IconTrashOutline16, { size: 16 }) })] })] })] }, item.id)) }), filtered.length > 50 && _jsxs("nav", { className: "dsh-ssh-command-pagination", "aria-label": t("commands-panel.commandPages"), children: [_jsxs("span", { children: [currentPage + 1, " / ", Math.ceil(filtered.length / 50), " ", t("commands-panel.pages"), " ", filtered.length, " ", t("commands-panel.items")] }), _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", disabled: currentPage === 0, onClick: () => setPage(currentPage - 1), children: t("commands-panel.previousPage") }), _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", disabled: (currentPage + 1) * 50 >= filtered.length, onClick: () => setPage(currentPage + 1), children: t("commands-panel.nextPage") })] }), editing && _jsx(CommandEditor, { value: editing === 'new' ? undefined : editing, onClose: () => setEditing(undefined), onSaved: () => { setEditing(undefined); void refresh(); } }), deleting && _jsxs(Dialog, { title: t("commands-panel.deleteSavedCommand"), subtitle: deleting.name, onClose: () => { if (!busy)
|
|
39
|
+
setDeleting(undefined); }, children: [_jsx("p", { children: t("commands-panel.onlyThisRecordIsDeletedRunningTerminalsAreNot") }), _jsxs("div", { className: "dsh-ssh-dialog-actions", children: [_jsx("button", { type: "button", className: "dsh-ssh-secondary-button", disabled: busy, onClick: () => setDeleting(undefined), children: t("client.cancel") }), _jsx("button", { type: "button", className: "dsh-ssh-danger-button", disabled: busy, onClick: () => {
|
|
37
40
|
setBusy(true);
|
|
38
41
|
void api(`/commands/${encodeURIComponent(deleting.id)}`, { method: 'DELETE' }).then(() => { setDeleting(undefined); return refresh(); }).catch(reason => setError(errorMessage(reason))).finally(() => setBusy(false));
|
|
39
|
-
}, children: busy ?
|
|
42
|
+
}, children: busy ? t("commands-panel.deleting") : t("client.delete") })] }), error && _jsx("p", { role: "alert", className: "dsh-ssh-inline-error", children: error })] })] });
|
|
40
43
|
}
|
|
41
44
|
function CommandEditor({ value, onClose, onSaved }) {
|
|
45
|
+
useSshLocale();
|
|
42
46
|
const [name, setName] = useState(value?.name ?? '');
|
|
43
47
|
const [command, setCommand] = useState(value?.command ?? '');
|
|
44
48
|
const [busy, setBusy] = useState(false);
|
|
45
49
|
const [error, setError] = useState();
|
|
46
|
-
return _jsx(Dialog, { title: value ?
|
|
50
|
+
return _jsx(Dialog, { title: value ? t("commands-panel.editCommand") : t("commands-panel.newCommand"), onClose: () => { if (!busy)
|
|
47
51
|
onClose(); }, children: _jsxs("form", { className: "dsh-ssh-form", onSubmit: event => {
|
|
48
52
|
event.preventDefault();
|
|
49
53
|
setBusy(true);
|
|
50
54
|
setError(undefined);
|
|
51
55
|
void api(value ? `/commands/${encodeURIComponent(value.id)}` : '/commands', { method: value ? 'PUT' : 'POST', body: JSON.stringify({ name, command }) }).then(onSaved).catch(reason => setError(errorMessage(reason))).finally(() => setBusy(false));
|
|
52
|
-
}, children: [_jsx(Field, { label: "
|
|
56
|
+
}, children: [_jsx(Field, { label: t("client.name"), children: _jsx("input", { required: true, maxLength: 80, value: name, onChange: event => setName(event.target.value) }) }), _jsx(Field, { label: t("commands-panel.command"), hint: t("commands-panel.multiLineScriptsAreSupportedRecordsStayInThis"), children: _jsx("textarea", { required: true, rows: 6, maxLength: 16000, value: command, onChange: event => setCommand(event.target.value) }) }), error && _jsx("p", { className: "dsh-ssh-inline-error", role: "alert", children: error }), _jsxs("div", { className: "dsh-ssh-dialog-actions", children: [_jsx("button", { type: "button", className: "dsh-ssh-secondary-button", disabled: busy, onClick: onClose, children: t("client.cancel") }), _jsx("button", { type: "submit", className: "dsh-ssh-primary-button", disabled: busy, children: busy ? t("client.saving2") : t("commands-panel.save") })] })] }) });
|
|
53
57
|
}
|
|
54
58
|
//# sourceMappingURL=commands-panel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-panel.js","sourceRoot":"","sources":["../src/commands-panel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAA;AAEhH,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEhE,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAA0D;IAChG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAiB,EAAE,CAAC,CAAA;IACtD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAU,CAAA;IAC5C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAwB,CAAA;IAC9D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACxD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC;YAAC,QAAQ,CAAC,MAAM,GAAG,CAAiB,WAAW,CAAC,CAAC,CAAC;YAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QAAC,CAAC;QAC7E,OAAO,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAA;QAAC,CAAC;gBACzC,CAAC;YAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAAC,CAAC;IAC/B,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,SAAS,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,EAAE,CAAA,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"commands-panel.js","sourceRoot":"","sources":["../src/commands-panel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
|
3
3
|
type PanelProps = PropsRuntime<'details'>;
|
|
4
4
|
/** The new host owns session persistence, docking and tab closure. */
|
|
5
5
|
export declare function supportsDockedPanels(ctx: Context): boolean;
|
|
6
|
-
export declare function createDockedPanel(ctx: Context, id: string, title: string, render: (props: PanelProps) => JSX.Element, notify: () => void): {
|
|
6
|
+
export declare function createDockedPanel(ctx: Context, id: string, title: string | (() => string), render: (props: PanelProps) => JSX.Element, notify: () => void): {
|
|
7
7
|
open(sessionId: string): void;
|
|
8
8
|
close(sessionId: string): void;
|
|
9
9
|
isOpen(sessionId: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docked-panel-compat.d.ts","sourceRoot":"","sources":["../src/docked-panel-compat.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGpE,KAAK,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;AAMzC,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"docked-panel-compat.d.ts","sourceRoot":"","sources":["../src/docked-panel-compat.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGpE,KAAK,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;AAMzC,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,EAC9B,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,GAAG,CAAC,OAAO,EAC1C,MAAM,EAAE,MAAM,IAAI;oBAmDA,MAAM,GAAG,IAAI;qBAwBZ,MAAM,GAAG,IAAI;sBAMZ,MAAM,GAAG,OAAO;eAGvB,IAAI;EAQlB"}
|
|
@@ -4,6 +4,7 @@ export function supportsDockedPanels(ctx) {
|
|
|
4
4
|
return typeof ctx.layout.selectPanel === 'function';
|
|
5
5
|
}
|
|
6
6
|
export function createDockedPanel(ctx, id, title, render, notify) {
|
|
7
|
+
const displayTitle = () => typeof title === 'function' ? title() : title;
|
|
7
8
|
const records = new Map();
|
|
8
9
|
let pending;
|
|
9
10
|
let frame;
|
|
@@ -48,7 +49,7 @@ export function createDockedPanel(ctx, id, title, render, notify) {
|
|
|
48
49
|
sidebar = child.get('sidebarRight');
|
|
49
50
|
const registry = child.get('sidebarRightTabs');
|
|
50
51
|
const slots = child.slots;
|
|
51
|
-
child.effect(() => registry.register({ id, kind: id, title:
|
|
52
|
+
child.effect(() => registry.register({ id, kind: id, title: displayTitle }), id + ': tab type');
|
|
52
53
|
child.effect(() => slots.inject('sidebar.right.pane.tab', () => slots.register({
|
|
53
54
|
name: 'sidebar.right.pane.tab', key: id,
|
|
54
55
|
}, Body)), id + ': tab body');
|
|
@@ -84,7 +85,7 @@ export function createDockedPanel(ctx, id, title, render, notify) {
|
|
|
84
85
|
else {
|
|
85
86
|
cancel();
|
|
86
87
|
notify();
|
|
87
|
-
console.error(
|
|
88
|
+
console.error(displayTitle() + ': could not open sidebar', error);
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docked-panel-compat.js","sourceRoot":"","sources":["../src/docked-panel-compat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAWjC,sEAAsE;AACtE,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,OAAO,OAAQ,GAAG,CAAC,MAA+C,CAAC,WAAW,KAAK,UAAU,CAAA;AAC/F,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,GAAY,EACZ,EAAU,EACV,
|
|
1
|
+
{"version":3,"file":"docked-panel-compat.js","sourceRoot":"","sources":["../src/docked-panel-compat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-entry-delete-dialog.d.ts","sourceRoot":"","sources":["../src/file-entry-delete-dialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-entry-delete-dialog.d.ts","sourceRoot":"","sources":["../src/file-entry-delete-dialog.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAGpD,wBAAgB,qBAAqB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAC;IAAC,OAAO,IAAI,IAAI,CAAC;IAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAgB/O"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useSshLocale } from './use-ssh-locale.js';
|
|
3
|
+
import { t } from './i18n.js';
|
|
2
4
|
import { useState } from 'react';
|
|
3
5
|
import { IconDataOutline16, IconFolderClose16, IconTrashOutline16 } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
6
|
import { Dialog, errorMessage } from './ui-components.js';
|
|
5
7
|
export function FileEntryDeleteDialog({ locationName, locationKind, entries, onClose, onDelete }) {
|
|
8
|
+
useSshLocale();
|
|
6
9
|
const [deleting, setDeleting] = useState(false);
|
|
7
10
|
const [error, setError] = useState();
|
|
8
11
|
const directories = entries.filter(entry => entry.kind === 'directory').length;
|
|
@@ -19,7 +22,7 @@ export function FileEntryDeleteDialog({ locationName, locationKind, entries, onC
|
|
|
19
22
|
setDeleting(false);
|
|
20
23
|
}
|
|
21
24
|
};
|
|
22
|
-
return _jsxs(Dialog, { className: "dsh-ssh-file-delete-dialog", title:
|
|
23
|
-
onClose(); }, children: [_jsxs("div", { className: "dsh-ssh-file-delete-copy", children: [_jsx("span", { children: _jsx(IconTrashOutline16, { size: 18 }) }), _jsxs("p", { children: ["
|
|
25
|
+
return _jsxs(Dialog, { className: "dsh-ssh-file-delete-dialog", title: t("file-entry-delete-dialog.deleteItems", [entries.length]), subtitle: t("file-entry-delete-dialog.thisCannotBeUndone", [locationName]), onClose: () => { if (!deleting)
|
|
26
|
+
onClose(); }, children: [_jsxs("div", { className: "dsh-ssh-file-delete-copy", children: [_jsx("span", { children: _jsx(IconTrashOutline16, { size: 18 }) }), _jsxs("p", { children: [t("file-entry-delete-dialog.deleteFromLocation", [locationKind === 'local' ? t("file-entry-delete-dialog.theCurrentSessionDirectory") : t("client.theRemote")]), directories > 0 ? t("file-entry-delete-dialog.ofTheseDirectoriesAndAllTheirContentsWillBe", [directories]) : ''] })] }), _jsxs("div", { className: "dsh-ssh-file-delete-list", children: [entries.slice(0, 6).map(entry => _jsxs("div", { children: [entry.kind === 'directory' ? _jsx(IconFolderClose16, { size: 17 }) : _jsx(IconDataOutline16, { size: 17 }), _jsxs("span", { children: [_jsx("strong", { children: entry.name }), _jsx("small", { title: entry.path, children: entry.path })] })] }, entry.path)), entries.length > 6 && _jsxs("p", { children: [t("file-entry-delete-dialog.andAnother"), " ", entries.length - 6, " ", t("file-entry-delete-dialog.items")] })] }), error && _jsx("p", { className: "dsh-ssh-inline-error", role: "alert", children: error }), _jsxs("div", { className: "dsh-ssh-dialog-actions", children: [_jsx("span", {}), _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", "data-ssh-dialog-close": true, disabled: deleting, onClick: onClose, children: t("client.cancel") }), _jsx("button", { type: "button", className: "dsh-ssh-danger-button", disabled: deleting, onClick: () => { void submit(); }, children: deleting ? t("file-entry-delete-dialog.deleting") : t("file-entry-delete-dialog.confirmDelete") })] })] });
|
|
24
27
|
}
|
|
25
28
|
//# sourceMappingURL=file-entry-delete-dialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-entry-delete-dialog.js","sourceRoot":"","sources":["../src/file-entry-delete-dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAA;AAEhH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEzD,MAAM,UAAU,qBAAqB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAoI;IAChO,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAU,CAAA;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,MAAM,CAAA;IAC9E,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;QACvC,WAAW,CAAC,IAAI,CAAC,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACtC,IAAI,CAAC;YAAC,MAAM,QAAQ,EAAE,CAAC;YAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,EAAE,CAAA;QAAC,CAAC;QACvD,OAAO,MAAM,EAAE,CAAC;YAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;YAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAAC,CAAC;IACvE,CAAC,CAAA;IACD,OAAO,MAAC,MAAM,IAAC,SAAS,EAAC,4BAA4B,EAAC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"file-entry-delete-dialog.js","sourceRoot":"","sources":["../src/file-entry-delete-dialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-transfer-workspace.d.ts","sourceRoot":"","sources":["../src/file-transfer-workspace.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-transfer-workspace.d.ts","sourceRoot":"","sources":["../src/file-transfer-workspace.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEkB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAoE,KAAK,cAAc,EACvJ,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAmB7D,wBAAgB,qBAAqB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE;IAAE,WAAW,EAAE,cAAc,EAAE,CAAC;IAAC,YAAY,EAAE,cAAc,EAAE,CAAC;IAAC,YAAY,EAAE,cAAc,EAAE,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,iBAAiB,IAAI,IAAI,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAuGnR"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useSshLocale } from './use-ssh-locale.js';
|
|
3
|
+
import { t } from './i18n.js';
|
|
2
4
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
5
|
import { IconChevronDownOutline14, IconChevronLeftOutline14, IconCloseOutline16, IconDataOutline16, IconPlusOutline16, IconTrashOutline16 } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
6
|
import { inspectFileEndpointEntry, cancelFileTransfer, deleteFileEndpointEntries, fileEndpointDownloadUrl, loadFileEndpointDirectory, loadFileEndpoints, loadTransferJobs, startFileTransfer, } from './client-api.js';
|
|
@@ -13,6 +15,7 @@ const STORAGE_KEY = 'dsh-ssh:file-transfer:tabs:v2';
|
|
|
13
15
|
const FILE_ROW_HEIGHT = 38;
|
|
14
16
|
const transferClockFormatter = new Intl.DateTimeFormat(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
15
17
|
export function FileTransferWorkspace({ ftpProfiles, vaultEntries, proxyEntries, access, onProfilesChanged }) {
|
|
18
|
+
useSshLocale();
|
|
16
19
|
const stageGlow = useBorderGlowSurface();
|
|
17
20
|
const [endpoints, setEndpoints] = useState([]);
|
|
18
21
|
const [jobs, setJobs] = useState([]);
|
|
@@ -127,7 +130,7 @@ export function FileTransferWorkspace({ ftpProfiles, vaultEntries, proxyEntries,
|
|
|
127
130
|
setError(errorMessage(reason));
|
|
128
131
|
}
|
|
129
132
|
};
|
|
130
|
-
return _jsxs("div", { className: "dsh-ssh-transfer-workspace", children: [_jsxs("header", { className: "dsh-ssh-transfer-header", children: [_jsxs("div", { children: [_jsx("h1", { children: "
|
|
133
|
+
return _jsxs("div", { className: "dsh-ssh-transfer-workspace", children: [_jsxs("header", { className: "dsh-ssh-transfer-header", children: [_jsxs("div", { children: [_jsx("h1", { children: t("client.fileTransfer") }), _jsx("p", { children: t("file-transfer-workspace.directStreamingTransfersBetweenFtpFtpsAndSftp") })] }), _jsxs("div", { className: "dsh-ssh-transfer-actions", children: [_jsxs("button", { type: "button", "data-ssh-interactive": "control", className: "dsh-ssh-secondary-button", onClick: () => setAccessOpen(true), children: [t("file-transfer-workspace.sessionAccess"), " ", access.value?.fileEndpointIds.length ?? 0] }), _jsx("button", { type: "button", "data-ssh-interactive": "control", className: "dsh-ssh-secondary-button", onClick: () => setConnectionsOpen(true), children: t("file-transfer-workspace.ftpManager") })] })] }), error && _jsxs("div", { className: "dsh-ssh-banner is-error", role: "alert", children: [_jsx("span", { children: error }), _jsx("button", { type: "button", onClick: () => setError(undefined), "aria-label": t("client.close"), children: _jsx(IconCloseOutline16, { size: 16 }) })] }), _jsxs("section", { ref: stageGlow.ref, onPointerMove: stageGlow.onPointerMove, onPointerLeave: stageGlow.onPointerLeave, className: "dsh-ssh-transfer-stage dsh-ssh-border-surface", children: [_jsxs("div", { className: "dsh-ssh-transfer-tabbar", role: "tablist", "aria-label": t("file-transfer-workspace.fileTransferTasksPage"), children: [_jsxs("div", { className: "dsh-ssh-transfer-tabs", children: [tabs.map(tab => _jsxs("span", { "data-ssh-interactive": "choice", className: `dsh-ssh-transfer-tab${tab.id === active?.id ? ' is-active' : ''}`, children: [_jsx("button", { type: "button", role: "tab", "aria-selected": tab.id === active?.id, onClick: () => setActiveTabId(tab.id), children: transferTabLabel(tab) }), tabs.length > 1 && _jsx("button", { type: "button", className: "is-close", "aria-label": t("file-transfer-workspace.close", [transferTabLabel(tab)]), onClick: () => closeTab(tab.id), children: _jsx(IconCloseOutline16, { size: 13 }) })] }, tab.id)), _jsx("button", { type: "button", "data-ssh-interactive": "control", className: "is-add", "aria-label": t("file-transfer-workspace.newTransferTasksPage"), onClick: addTab, children: _jsx(IconPlusOutline16, { size: 15 }) })] }), _jsx("div", { className: "dsh-ssh-pane-layout", "aria-label": t("file-transfer-workspace.panes"), children: [2, 3, 4].map(count => _jsxs("button", { type: "button", "data-ssh-interactive": "choice", "aria-pressed": active?.panes.length === count, className: active?.panes.length === count ? 'is-active' : '', onClick: () => setPaneCount(count), children: [count, " ", t("file-transfer-workspace.panes2")] }, count)) })] }), endpoints.length === 0 ? _jsxs("div", { className: "dsh-ssh-transfer-empty", children: [_jsx(IconDataOutline16, { size: 24 }), _jsx("strong", { children: t("file-transfer-workspace.noFileConnectionsAvailableYet") }), _jsx("p", { children: t("file-transfer-workspace.createAnFtpFtpsConnectionOrAddAnSsh") }), _jsx("button", { type: "button", className: "dsh-ssh-primary-button", onClick: () => setConnectionsOpen(true), children: t("file-transfer-workspace.newFtpConnection") })] })
|
|
131
134
|
: active && _jsx("div", { className: `dsh-ssh-transfer-panes has-${active.panes.length}`, children: active.panes.map((pane, index) => {
|
|
132
135
|
const destination = active.panes[(index + 1) % active.panes.length];
|
|
133
136
|
return _jsx(FileTransferPane, { pane: pane, endpoints: endpoints, dragSource: dragSource, refreshRevision: directoryRevisions[directoryKey(pane.endpointId, pane.path)] ?? 0, ...destination === undefined ? {} : { destination }, onManageConnections: () => setConnectionsOpen(true), onDragSourceChange: setDragSource, onChange: patch => updateActive(tab => ({ ...tab, panes: tab.panes.map(item => item.id === pane.id ? { ...item, ...patch } : item) })), onTransfer: (paths, target) => { void transfer(pane.endpointId, pane.path, paths, target.endpointId, target.path); }, onExternalDrop: (source, destinationDirectory) => { void dropFiles(source, pane, destinationDirectory); } }, pane.id);
|
|
@@ -147,6 +150,7 @@ export function FileTransferWorkspace({ ftpProfiles, vaultEntries, proxyEntries,
|
|
|
147
150
|
} } })] });
|
|
148
151
|
}
|
|
149
152
|
function FileTransferPane({ pane, endpoints, destination, dragSource, refreshRevision, onChange, onTransfer, onExternalDrop, onDragSourceChange, onManageConnections }) {
|
|
153
|
+
const sshLocale = useSshLocale();
|
|
150
154
|
const [openedFile, setOpenedFile] = useState();
|
|
151
155
|
const [view, setView] = useState();
|
|
152
156
|
const [selected, setSelected] = useState([]);
|
|
@@ -161,10 +165,10 @@ function FileTransferPane({ pane, endpoints, destination, dragSource, refreshRev
|
|
|
161
165
|
const bodyRef = useRef(null);
|
|
162
166
|
const loadGenerationRef = useRef(0);
|
|
163
167
|
const endpoint = endpoints.find(item => item.id === pane.endpointId);
|
|
164
|
-
const entries = useMemo(() => sortFileEntries(view?.entries ?? [], sort.key, sort.direction), [view?.entries, sort]);
|
|
168
|
+
const entries = useMemo(() => sortFileEntries(view?.entries ?? [], sort.key, sort.direction), [view?.entries, sort, sshLocale]);
|
|
165
169
|
const virtualized = entries.length > 200;
|
|
166
170
|
const virtualStart = virtualized ? Math.max(0, Math.floor(scrollTop / FILE_ROW_HEIGHT) - 8) : 0;
|
|
167
|
-
const visibleEntries = useMemo(() => virtualized ? entries.slice(virtualStart, Math.min(entries.length, virtualStart + 56)) : entries, [entries, virtualStart, virtualized]);
|
|
171
|
+
const visibleEntries = useMemo(() => virtualized ? entries.slice(virtualStart, Math.min(entries.length, virtualStart + 56)) : entries, [entries, virtualStart, virtualized, sshLocale]);
|
|
168
172
|
const load = useCallback(async (path = pane.path) => {
|
|
169
173
|
if (endpoint === undefined)
|
|
170
174
|
return;
|
|
@@ -254,7 +258,7 @@ function FileTransferPane({ pane, endpoints, destination, dragSource, refreshRev
|
|
|
254
258
|
onExternalDrop(payload, pane.path);
|
|
255
259
|
};
|
|
256
260
|
if (endpoint === undefined)
|
|
257
|
-
return _jsxs("section", { className: "dsh-ssh-file-pane is-connections", children: [_jsxs("header", { children: [_jsxs("span", { className: "dsh-ssh-pane-heading", children: [_jsx("strong", { children: "
|
|
261
|
+
return _jsxs("section", { className: "dsh-ssh-file-pane is-connections", children: [_jsxs("header", { children: [_jsxs("span", { className: "dsh-ssh-pane-heading", children: [_jsx("strong", { children: t("file-transfer-workspace.connectionList") }), _jsx("small", { children: t("file-transfer-workspace.clickAConnectionToBrowseRemoteFiles") })] }), _jsx("button", { type: "button", "data-ssh-interactive": "control", className: "dsh-ssh-pane-manage-button", onClick: onManageConnections, children: t("file-transfer-workspace.ftpManager") })] }), _jsx("div", { className: "dsh-ssh-endpoint-list", children: endpoints.map(item => _jsxs("button", { type: "button", "data-ssh-interactive": "row", className: "dsh-ssh-endpoint-row", onClick: () => chooseEndpoint(item), children: [_jsx("span", { className: `dsh-ssh-protocol-badge is-${item.protocol}`, children: protocolShort(item.protocol) }), _jsxs("span", { children: [_jsx("strong", { title: item.name, children: item.name }), _jsx("small", { title: item.address, children: item.address })] }), _jsxs("span", { children: [_jsx("i", { className: `dsh-ssh-protocol-dot is-${item.protocol}`, "aria-hidden": "true" }), item.group ?? (item.kind === 'sftp' ? t("file-transfer-workspace.sshHosts") : t("file-transfer-workspace.fileConnections"))] })] }, item.id)) }), _jsxs("footer", { children: [_jsxs("span", { children: [endpoints.length, " ", t("file-transfer-workspace.availableConnections")] }), _jsx("small", { children: t("file-transfer-workspace.sftpReusesSshHostConfiguration") })] })] });
|
|
258
262
|
return _jsxs("section", { className: `dsh-ssh-file-pane${dragOver ? ' is-drop-target' : ''}`, onDragOver: event => { if (event.dataTransfer.types.includes(REMOTE_FILES_DRAG_TYPE) && canDropIntoPane(dragSource, pane)) {
|
|
259
263
|
event.preventDefault();
|
|
260
264
|
event.dataTransfer.dropEffect = dragSource?.endpointId === pane.endpointId ? 'move' : 'copy';
|
|
@@ -265,12 +269,13 @@ function FileTransferPane({ pane, endpoints, destination, dragSource, refreshRev
|
|
|
265
269
|
setDragOver(false); }, onDragLeave: event => { if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
266
270
|
setDragOver(false);
|
|
267
271
|
setDirectoryDropTarget(undefined);
|
|
268
|
-
} }, onDrop: drop, children: [_jsxs("header", { children: [_jsx("button", { type: "button", className: "dsh-ssh-pane-back", "aria-label": "
|
|
269
|
-
void load(view.parent); }, children: _jsx(UpGlyph, {}) }), _jsx("button", { type: "button", "aria-label": "
|
|
270
|
-
setScrollTop(event.currentTarget.scrollTop); }, children: loading && !view ? _jsx("div", { className: "dsh-ssh-file-loading", children: "
|
|
271
|
-
onTransfer(selected, destination); }, children: ["
|
|
272
|
+
} }, onDrop: drop, children: [_jsxs("header", { children: [_jsx("button", { type: "button", className: "dsh-ssh-pane-back", "aria-label": t("file-transfer-workspace.backToConnectionList"), onClick: showConnections, children: _jsx(IconChevronLeftOutline14, { size: 14 }) }), _jsxs("span", { className: "dsh-ssh-pane-endpoint", children: [_jsx("strong", { children: endpoint.name }), _jsx("small", { title: endpoint.address, children: endpoint.address })] }), _jsx("span", { className: `dsh-ssh-protocol-badge is-${endpoint.protocol}`, children: protocolShort(endpoint.protocol) })] }), _jsxs("form", { className: "dsh-ssh-file-pathbar", onSubmit: submitPath, children: [_jsx("button", { type: "button", "aria-label": t("file-transfer-workspace.parentDirectory"), disabled: view?.parent === null || loading, onClick: () => { if (view?.parent)
|
|
273
|
+
void load(view.parent); }, children: _jsx(UpGlyph, {}) }), _jsx("button", { type: "button", "aria-label": t("file-transfer-workspace.refreshDirectory"), disabled: loading, onClick: () => { void load(); }, children: _jsx(RefreshGlyph, {}) }), _jsx("input", { "aria-label": t("file-transfer-workspace.remotePath"), value: draftPath, onChange: event => setDraftPath(event.target.value) }), _jsx("button", { type: "submit", disabled: loading, children: t("file-transfer-workspace.goTo") })] }), _jsxs("div", { className: "dsh-ssh-file-table", role: "grid", "aria-busy": loading, children: [_jsxs("div", { className: "dsh-ssh-file-table-head", role: "row", children: [_jsx(SortColumn, { label: t("client.name"), sortKey: "name", current: sort, onSort: changeSort }), _jsx(SortColumn, { label: t("file-transfer-workspace.size"), sortKey: "size", current: sort, onSort: changeSort }), _jsx(SortColumn, { label: t("file-transfer-workspace.modified"), sortKey: "modifiedAt", current: sort, onSort: changeSort }), _jsx("span", { role: "columnheader", "aria-label": t("file-transfer-workspace.actions") })] }), _jsx("div", { ref: bodyRef, className: "dsh-ssh-file-table-body", onScroll: event => { if (virtualized)
|
|
274
|
+
setScrollTop(event.currentTarget.scrollTop); }, children: loading && !view ? _jsx("div", { className: "dsh-ssh-file-loading", children: t("file-transfer-workspace.readingDirectory") }) : error ? _jsxs("div", { className: "dsh-ssh-file-error", children: [_jsx("span", { children: error }), _jsx("button", { type: "button", onClick: () => { void load(); }, children: t("commands-panel.retry") })] }) : entries.length === 0 ? _jsx("div", { className: "dsh-ssh-table-empty", children: t("file-transfer-workspace.thisDirectoryIsEmpty") }) : _jsx("div", { className: virtualized ? 'dsh-ssh-file-virtual-list' : undefined, style: virtualized ? { height: `${entries.length * FILE_ROW_HEIGHT}px` } : undefined, children: visibleEntries.map((entry, offset) => _jsx(FileEntryRow, { entry: entry, paneId: pane.id, endpointId: endpoint.id, sourceDirectory: view?.path ?? pane.path, dragSource: dragSource, dropTarget: directoryDropTarget === entry.path, selected: selected.includes(entry.path), selectedPaths: selected, ...virtualized ? { style: { position: 'absolute', insetInline: 0, transform: `translateY(${(virtualStart + offset) * FILE_ROW_HEIGHT}px)` } } : {}, onDelete: () => setDeleteTarget([entry]), onDirectoryTarget: target => { setDragOver(false); setDirectoryDropTarget(target); }, onDropIntoDirectory: (payload, target) => { setDirectoryDropTarget(undefined); onDragSourceChange(undefined); onExternalDrop(payload, target); }, onDragSourceChange: onDragSourceChange, onSelect: additive => select(entry, additive), onOpen: () => { void openEntry(entry.path); } }, entry.path)) }) })] }), _jsxs("footer", { children: [_jsx("span", { children: selected.length > 0 ? t("file-transfer-workspace.selectedItems", [selected.length]) : t("file-transfer-workspace.items", [view?.entries.length ?? 0]) }), _jsx("span", { className: "dsh-ssh-file-pane-actions", children: _jsxs("button", { type: "button", "data-ssh-interactive": "control", className: "dsh-ssh-transfer-to-button", disabled: selected.length === 0 || destination === undefined || !destination.endpointId || loading, onClick: () => { if (destination?.endpointId)
|
|
275
|
+
onTransfer(selected, destination); }, children: [t("file-transfer-workspace.sendToNextPane"), " ", _jsx("span", { "aria-hidden": "true", children: "\u2192" })] }) })] }), dragOver && _jsxs("div", { className: "dsh-ssh-file-drop-overlay", children: [_jsx("strong", { children: dragSource?.endpointId === pane.endpointId ? t("file-transfer-workspace.moveToThisDirectory") : t("file-transfer-workspace.copyToThisDirectory") }), _jsx("span", { children: view?.path ?? pane.path })] }), openedFile !== undefined && _jsx(Dialog, { className: "dsh-ssh-file-download-dialog", title: openedFile.name, subtitle: openedFile.path, onClose: () => setOpenedFile(undefined), children: _jsx("div", { className: "dsh-ssh-dialog-actions", children: _jsxs("a", { className: "dsh-ssh-secondary-button", href: fileEndpointDownloadUrl(endpoint.id, openedFile.path), download: true, children: [_jsx(DownloadGlyph, {}), _jsx("span", { children: t("file-transfer-workspace.download") })] }) }) }), deleteTarget !== undefined && _jsx(FileEntryDeleteDialog, { locationName: endpoint.name, locationKind: "remote", entries: deleteTarget, onClose: () => setDeleteTarget(undefined), onDelete: removeSelected })] });
|
|
272
276
|
}
|
|
273
277
|
function SortColumn({ label, sortKey, current, onSort }) {
|
|
278
|
+
useSshLocale();
|
|
274
279
|
const active = current.key === sortKey;
|
|
275
280
|
return _jsx("span", { role: "columnheader", "aria-sort": active ? (current.direction === 'asc' ? 'ascending' : 'descending') : 'none', children: _jsxs("button", { type: "button", onClick: () => onSort(sortKey), children: [label, _jsx(SortGlyph, { active: active, direction: current.direction })] }) });
|
|
276
281
|
}
|
|
@@ -281,6 +286,7 @@ function DownloadGlyph() {
|
|
|
281
286
|
return _jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.4, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "M8 2v7m0 0 2.6-2.6M8 9 5.4 6.4M3 11.5v1.25h10V11.5" }) });
|
|
282
287
|
}
|
|
283
288
|
function FileEntryRow({ entry, paneId, endpointId, sourceDirectory, dragSource, dropTarget, selected, selectedPaths, style, onSelect, onOpen, onDelete, onDirectoryTarget, onDropIntoDirectory, onDragSourceChange }) {
|
|
289
|
+
useSshLocale();
|
|
284
290
|
const directory = isNavigableRemoteEntry(entry);
|
|
285
291
|
// FTP defers unknown/link resolution until navigation; unverified entries
|
|
286
292
|
// must not become directory drop targets or recursive transfer roots.
|
|
@@ -297,7 +303,7 @@ function FileEntryRow({ entry, paneId, endpointId, sourceDirectory, dragSource,
|
|
|
297
303
|
if (payload !== undefined && canTransferIntoRemoteDirectory(payload, payload.paths, { endpointId, directory: entry.path }))
|
|
298
304
|
onDropIntoDirectory(payload, entry.path);
|
|
299
305
|
};
|
|
300
|
-
return _jsxs("div", { role: "row", "data-ssh-interactive": "row", "data-ssh-context-row": true, tabIndex: 0, "aria-selected": selected, "aria-label": `${entry.name}${directory ?
|
|
306
|
+
return _jsxs("div", { role: "row", "data-ssh-interactive": "row", "data-ssh-context-row": true, tabIndex: 0, "aria-selected": selected, "aria-label": `${entry.name}${directory ? t("file-transfer-workspace.directoryClickToEnterAcceptsDragDrop") : probeOnOpen ? t("file-transfer-workspace.clickToView") : ''}`, draggable: entry.kind === 'file' || directory, className: `dsh-ssh-file-row is-${directory ? 'directory' : entry.kind}${selected ? ' is-selected' : ''}${dropTarget ? ' is-drop-target' : ''}`, style: style, onClick: event => { if (canOpen && !event.ctrlKey && !event.metaKey && !event.shiftKey)
|
|
301
307
|
onOpen();
|
|
302
308
|
else
|
|
303
309
|
onSelect(event.ctrlKey || event.metaKey); }, onKeyDown: event => { if (event.target !== event.currentTarget)
|
|
@@ -311,38 +317,45 @@ function FileEntryRow({ entry, paneId, endpointId, sourceDirectory, dragSource,
|
|
|
311
317
|
event.dataTransfer.dropEffect = dragSource?.endpointId === endpointId ? 'move' : 'copy';
|
|
312
318
|
onDirectoryTarget(entry.path);
|
|
313
319
|
} }, onDragLeave: event => { if (dropTarget && !event.currentTarget.contains(event.relatedTarget))
|
|
314
|
-
onDirectoryTarget(undefined); }, onDrop: dropIntoDirectory, children: [_jsxs("span", { children: [_jsx(FileGlyph, { directory: directory }), _jsx("i", { title: entry.name, children: entry.name })] }), _jsx("span", { children: directory ? '—' : formatBytes(entry.size) }), _jsx("span", { children: entry.modifiedAt > 0 ? new Date(entry.modifiedAt).toLocaleString() : '—' }), _jsxs("span", { className: "dsh-ssh-file-row-actions dsh-ssh-context-action", children: [_jsx("a", { className: "dsh-ssh-file-row-download", href: fileEndpointDownloadUrl(endpointId, entry.path), download: true, draggable: false, "aria-label":
|
|
320
|
+
onDirectoryTarget(undefined); }, onDrop: dropIntoDirectory, children: [_jsxs("span", { children: [_jsx(FileGlyph, { directory: directory }), _jsx("i", { title: entry.name, children: entry.name })] }), _jsx("span", { children: directory ? '—' : formatBytes(entry.size) }), _jsx("span", { children: entry.modifiedAt > 0 ? new Date(entry.modifiedAt).toLocaleString() : '—' }), _jsxs("span", { className: "dsh-ssh-file-row-actions dsh-ssh-context-action", children: [_jsx("a", { className: "dsh-ssh-file-row-download", href: fileEndpointDownloadUrl(endpointId, entry.path), download: true, draggable: false, "aria-label": t("file-transfer-workspace.downloadLocally", [entry.name]), title: entry.kind === 'directory' ? t("file-transfer-workspace.packageAndDownloadLocally", [entry.name]) : t("file-transfer-workspace.downloadLocally", [entry.name]), onClick: event => event.stopPropagation(), children: _jsx(DownloadGlyph, {}) }), _jsx("button", { type: "button", className: "dsh-ssh-file-row-delete", draggable: false, "aria-label": t("client.delete2", [entry.name]), title: t("client.delete2", [entry.name]), onClick: event => { event.stopPropagation(); onDelete(); }, children: _jsx(IconTrashOutline16, { size: 14 }) })] })] });
|
|
315
321
|
}
|
|
316
322
|
function TransferQueue({ jobs, endpoints, onCancel, onConflict }) {
|
|
323
|
+
useSshLocale();
|
|
317
324
|
const [open, setOpen] = useState(true);
|
|
318
325
|
const active = jobs.filter(job => job.state === 'queued' || job.state === 'scanning' || job.state === 'transferring');
|
|
319
|
-
return _jsxs("section", { className: `dsh-ssh-transfer-queue${open ? ' is-open' : ''}`, children: [_jsxs("button", { type: "button", className: "dsh-ssh-transfer-queue-heading", "aria-expanded": open, title: open ?
|
|
326
|
+
return _jsxs("section", { className: `dsh-ssh-transfer-queue${open ? ' is-open' : ''}`, children: [_jsxs("button", { type: "button", className: "dsh-ssh-transfer-queue-heading", "aria-expanded": open, title: open ? t("file-transfer-workspace.collapseTransferTasks") : t("file-transfer-workspace.expandTransferTasks"), onClick: () => setOpen(value => !value), children: [_jsxs("span", { children: [_jsx("strong", { children: t("file-transfer-workspace.transferTasks") }), _jsx("small", { children: active.length > 0 ? t("file-transfer-workspace.inProgress", [active.length]) : jobs.length > 0 ? t("file-transfer-workspace.recentTasks") : t("file-transfer-workspace.noTasksYet") })] }), _jsx("span", { className: "dsh-ssh-transfer-queue-disclosure", "aria-hidden": "true", children: _jsx(IconChevronDownOutline14, { size: 14 }) })] }), open && _jsx("div", { className: "dsh-ssh-transfer-job-list", children: jobs.length === 0 ? _jsx("p", { children: t("file-transfer-workspace.dragFromOnePaneToAnotherOrSelectFiles") }) : jobs.slice(0, 12).map(job => {
|
|
320
327
|
const progress = job.totalBytes > 0 ? Math.min(100, job.transferredBytes / job.totalBytes * 100) : job.state === 'completed' ? 100 : 0;
|
|
321
|
-
return _jsxs("article", { children: [_jsx("span", { className: `dsh-ssh-transfer-state is-${job.state}`, "aria-hidden": "true" }), _jsxs("span", { className: "dsh-ssh-transfer-job-copy", children: [_jsxs("strong", { children: [remoteLabel(job.request.sourcePaths), " ", _jsx("i", { children: "\u2192" }), " ", endpointName(endpoints, job.request.destinationEndpointId)] }), _jsx("small", { children: job.error ?? jobLabel(job, progress) }), _jsx("span", { className: "dsh-ssh-transfer-job-time", children: jobTimeLabel(job) }), _jsx("span", { className: "dsh-ssh-transfer-progress", children: _jsx("i", { style: { transform: `scaleX(${progress / 100})` } }) })] }), (job.state === 'queued' || job.state === 'scanning' || job.state === 'transferring') ? _jsx("button", { type: "button", className: "dsh-ssh-icon-button", "aria-label": "
|
|
328
|
+
return _jsxs("article", { children: [_jsx("span", { className: `dsh-ssh-transfer-state is-${job.state}`, "aria-hidden": "true" }), _jsxs("span", { className: "dsh-ssh-transfer-job-copy", children: [_jsxs("strong", { children: [remoteLabel(job.request.sourcePaths), " ", _jsx("i", { children: "\u2192" }), " ", endpointName(endpoints, job.request.destinationEndpointId)] }), _jsx("small", { children: job.error ?? jobLabel(job, progress) }), _jsx("span", { className: "dsh-ssh-transfer-job-time", children: jobTimeLabel(job) }), _jsx("span", { className: "dsh-ssh-transfer-progress", children: _jsx("i", { style: { transform: `scaleX(${progress / 100})` } }) })] }), (job.state === 'queued' || job.state === 'scanning' || job.state === 'transferring') ? _jsx("button", { type: "button", className: "dsh-ssh-icon-button", "aria-label": t("file-transfer-workspace.cancelTransfer"), onClick: () => { void onCancel(job.id); }, children: _jsx(IconCloseOutline16, { size: 15 }) }) : job.state === 'failed' && job.error?.includes('destination already contains') ? _jsx("button", { type: "button", className: "dsh-ssh-job-resolve", onClick: () => onConflict(job), children: t("file-transfer-workspace.handle") }) : null] }, job.id);
|
|
322
329
|
}) })] });
|
|
323
330
|
}
|
|
324
331
|
function ConflictDialog({ job, onClose, onRetry }) {
|
|
332
|
+
useSshLocale();
|
|
325
333
|
const [policy, setPolicy] = useState('rename');
|
|
326
334
|
const [saving, setSaving] = useState(false);
|
|
327
|
-
return _jsxs(Dialog, { className: "dsh-ssh-transfer-conflict-dialog", title: "
|
|
335
|
+
return _jsxs(Dialog, { className: "dsh-ssh-transfer-conflict-dialog", title: t("file-transfer-workspace.aFileWithTheSameNameExistsAtThe"), subtitle: t("file-transfer-workspace.chooseHowToHandleThisBatchOfTransfers"), onClose: onClose, children: [_jsxs("div", { className: "dsh-ssh-transfer-conflict-copy", children: [_jsx("strong", { children: remoteLabel(job.request.sourcePaths) }), _jsx("span", { children: job.request.destinationDirectory })] }), _jsx("div", { className: "dsh-ssh-conflict-options", children: [['rename', t("file-transfer-workspace.autoRename"), t("file-transfer-workspace.keepBothFilesAppendANumberToTheName")], ['skip', t("file-transfer-workspace.skipFilesWithTheSameName"), t("file-transfer-workspace.continueTransferringTheRemainingItems")], ['overwrite', t("file-transfer-workspace.overwriteTheTargetFiles"), t("file-transfer-workspace.replaceTheDestinationContentWithTheSourceContent")]].map(option => _jsxs("button", { type: "button", "data-ssh-interactive": "choice", "aria-pressed": policy === option[0], className: policy === option[0] ? 'is-active' : '', onClick: () => setPolicy(option[0]), children: [_jsx("i", { "aria-hidden": "true" }), _jsxs("span", { children: [_jsx("strong", { children: option[1] }), _jsx("small", { children: option[2] })] })] }, option[0])) }), _jsxs("div", { className: "dsh-ssh-dialog-actions", children: [_jsx("button", { type: "button", className: "dsh-ssh-secondary-button", "data-ssh-dialog-close": true, onClick: onClose, children: t("client.cancel") }), _jsx("button", { type: "button", className: "dsh-ssh-primary-button", disabled: saving, onClick: () => { setSaving(true); void onRetry(policy).finally(() => setSaving(false)); }, children: saving ? t("file-transfer-workspace.reQueuing") : t("file-transfer-workspace.continueTransfer") })] })] });
|
|
328
336
|
}
|
|
329
337
|
function FileAccessDialog({ endpoints, access, onClose }) {
|
|
338
|
+
useSshLocale();
|
|
330
339
|
const value = access.value;
|
|
331
340
|
const mounted = endpoints.filter(endpoint => value?.fileEndpointIds.includes(endpoint.id)).length;
|
|
332
341
|
const toggle = (id) => access.setFileEndpoints(value?.fileEndpointIds.includes(id) ? value.fileEndpointIds.filter(item => item !== id) : [...(value?.fileEndpointIds ?? []), id]);
|
|
333
|
-
return _jsxs(Dialog, { className: "dsh-ssh-file-access-dialog", title: "
|
|
342
|
+
return _jsxs(Dialog, { className: "dsh-ssh-file-access-dialog", title: t("file-transfer-workspace.sessionAccess2"), subtitle: t("file-transfer-workspace.manageTheRemoteFileConnectionsAvailableToThisSession"), onClose: onClose, children: [_jsxs("div", { className: "dsh-ssh-file-access-body dsh-ssh-scroll-surface", children: [access.error && _jsx("p", { className: "dsh-ssh-inline-error", role: "alert", children: access.error }), _jsxs("section", { className: "dsh-ssh-file-access-section", "aria-labelledby": "dsh-ssh-file-access-connections", children: [_jsxs("header", { children: [_jsxs("span", { children: [_jsx("strong", { id: "dsh-ssh-file-access-connections", children: t("file-transfer-workspace.fileConnections") }), _jsx("small", { children: t("file-transfer-workspace.letTheCurrentSessionBrowseSelectedFtpFtpsOr") })] }), _jsxs("i", { children: [mounted.toString().padStart(2, '0'), " / ", endpoints.length.toString().padStart(2, '0')] })] }), _jsx("div", { className: "dsh-ssh-file-access-list", children: access.loading ? _jsx(FileAccessSkeleton, {}) : endpoints.length === 0 ? _jsxs("div", { className: "dsh-ssh-file-access-empty", children: [_jsx("strong", { children: t("file-transfer-workspace.noConnectionsAvailable") }), _jsx("small", { children: t("file-transfer-workspace.addAnFtpInFileTransferFirstOrAdd") })] }) : endpoints.map(endpoint => _jsx(FileAccessEndpoint, { endpoint: endpoint, enabled: value?.fileEndpointIds.includes(endpoint.id) ?? false, onToggle: () => toggle(endpoint.id) }, endpoint.id)) })] }), _jsxs("section", { className: "dsh-ssh-file-access-section is-options", "aria-labelledby": "dsh-ssh-file-access-policy", children: [_jsx("header", { children: _jsxs("span", { children: [_jsx("strong", { id: "dsh-ssh-file-access-policy", children: t("file-transfer-workspace.accessPolicy") }), _jsx("small", { children: t("file-transfer-workspace.filePermissionsAreSeparateFromSshCommandAndTerminal") })] }) }), _jsxs("div", { className: "dsh-ssh-file-access-options", children: [_jsxs("div", { className: "dsh-ssh-file-access-policy-row", children: [_jsxs("span", { children: [_jsx("strong", { children: t("file-transfer-workspace.fileOperationPermissions") }), _jsx("small", { children: t("file-transfer-workspace.browseModeDoesNotExposeCrossEndpointTransferTools") })] }), _jsx(FilePermissionPicker, { value: value?.filePermission ?? 'browse', onChange: access.setFilePermission })] }), _jsxs("div", { className: "dsh-ssh-file-access-policy-row", children: [_jsxs("span", { children: [_jsx("strong", { children: t("file-transfer-workspace.confirmBeforeTransfer") }), _jsx("small", { children: t("file-transfer-workspace.requireDshApprovalWhenTheAiStartsATransfer") })] }), _jsx(FileApprovalSwitch, { checked: value?.requireFileApproval ?? true, onChange: access.setRequireFileApproval })] })] })] })] }), _jsxs("footer", { className: "dsh-ssh-file-access-footer", children: [_jsxs("span", { className: access.saving ? 'is-saving' : 'is-saved', children: [_jsx("i", { "aria-hidden": "true" }), access.saving ? t("file-transfer-workspace.savingChanges") : t("file-transfer-workspace.autosaves", [mounted > 0 ? t("file-transfer-workspace.authorizedConnections", [mounted]) : t("file-transfer-workspace.noAuthorizedConnections")])] }), _jsx("button", { type: "button", className: "dsh-ssh-primary-button", "data-ssh-dialog-close": true, disabled: access.saving, onClick: onClose, children: access.saving ? t("client.saving2") : t("file-transfer-workspace.done") })] })] });
|
|
334
343
|
}
|
|
335
344
|
function FileAccessEndpoint({ endpoint, enabled, onToggle }) {
|
|
336
|
-
|
|
345
|
+
useSshLocale();
|
|
346
|
+
return _jsxs("button", { type: "button", "data-ssh-interactive": "choice", className: `dsh-ssh-file-access-endpoint${enabled ? ' is-mounted' : ''}`, "aria-pressed": enabled, onClick: onToggle, children: [_jsx("span", { className: `dsh-ssh-protocol-badge is-${endpoint.protocol}`, children: protocolShort(endpoint.protocol) }), _jsxs("span", { className: "dsh-ssh-file-access-endpoint-copy", children: [_jsx("strong", { title: endpoint.name, children: endpoint.name }), _jsx("small", { title: endpoint.address, children: endpoint.address })] }), _jsxs("span", { className: "dsh-ssh-file-access-state", children: [_jsx("i", { "aria-hidden": "true", children: _jsx("b", {}) }), _jsx("em", { children: enabled ? t("file-transfer-workspace.authorized") : t("file-transfer-workspace.notAuthorized") })] })] });
|
|
337
347
|
}
|
|
338
348
|
function FileAccessSkeleton() {
|
|
339
|
-
|
|
349
|
+
useSshLocale();
|
|
350
|
+
return _jsx("div", { className: "dsh-ssh-file-access-skeleton", "aria-label": t("file-transfer-workspace.readingSessionPermissions"), children: [0, 1, 2].map(index => _jsxs("span", { style: { '--ssh-skeleton-index': index }, children: [_jsx("i", {}), _jsxs("b", { children: [_jsx("i", {}), _jsx("i", {})] }), _jsx("em", {})] }, index)) });
|
|
340
351
|
}
|
|
341
352
|
function FilePermissionPicker({ value, onChange }) {
|
|
342
|
-
|
|
353
|
+
useSshLocale();
|
|
354
|
+
return _jsx("div", { className: "dsh-ssh-file-permission-picker", role: "radiogroup", "aria-label": t("file-transfer-workspace.fileOperationPermissions"), children: [['browse', t("file-transfer-workspace.browseOnly")], ['transfer', t("file-transfer-workspace.allowTransfer")]].map(([id, label]) => _jsx("button", { type: "button", "data-ssh-interactive": "choice", role: "radio", "aria-checked": value === id, className: value === id ? 'is-active' : '', onClick: () => onChange(id), children: label }, id)) });
|
|
343
355
|
}
|
|
344
356
|
function FileApprovalSwitch({ checked, onChange }) {
|
|
345
|
-
|
|
357
|
+
useSshLocale();
|
|
358
|
+
return _jsxs("button", { type: "button", "data-ssh-interactive": "choice", role: "switch", "aria-checked": checked, className: `dsh-ssh-file-approval-switch${checked ? ' is-active' : ''}`, onClick: () => onChange(!checked), children: [_jsx("i", { "aria-hidden": "true", children: _jsx("b", {}) }), _jsx("span", { children: checked ? t("file-transfer-workspace.confirmationRequired") : t("file-transfer-workspace.runDirectly") })] });
|
|
346
359
|
}
|
|
347
360
|
function restoreTabs() {
|
|
348
361
|
try {
|
|
@@ -372,10 +385,15 @@ function restoreTabs() {
|
|
|
372
385
|
return [createTab('transfer-1', 1)];
|
|
373
386
|
}
|
|
374
387
|
function createTab(id, index) { return { id, name: `任务 ${index}`, panes: [createPane(`${id}-a`), createPane(`${id}-b`)] }; }
|
|
388
|
+
function transferTabLabel(tab) {
|
|
389
|
+
// Keep the existing persisted representation; only translate generated display labels.
|
|
390
|
+
const number = /^任务 (\d+)$/.exec(tab.name)?.[1];
|
|
391
|
+
return number === undefined ? tab.name : t('file-transfer-workspace.tasks', [number]);
|
|
392
|
+
}
|
|
375
393
|
function createPane(id) { return { id, endpointId: '', path: '/' }; }
|
|
376
394
|
function normalizeTabs(tabs, endpoints) { return tabs.map(tab => ({ ...tab, panes: tab.panes.map(pane => !pane.endpointId || endpoints.some(item => item.id === pane.endpointId) ? pane : createPane(pane.id)) })); }
|
|
377
395
|
function endpointName(endpoints, id) { return endpoints.find(endpoint => endpoint.id === id)?.name ?? id; }
|
|
378
|
-
function remoteLabel(paths) { const name = paths[0]?.replaceAll('\\', '/').split('/').filter(Boolean).at(-1) ??
|
|
396
|
+
function remoteLabel(paths) { const name = paths[0]?.replaceAll('\\', '/').split('/').filter(Boolean).at(-1) ?? t("file-transfer-workspace.files"); return paths.length > 1 ? t("file-transfer-workspace.andMore", [name, paths.length]) : name; }
|
|
379
397
|
function protocolShort(protocol) { return protocol === 'sftp' ? 'SFTP' : protocol === 'ftp' ? 'FTP' : protocol === 'ftps-explicit' ? 'FTPS' : 'FTPS-I'; }
|
|
380
398
|
function directoryKey(endpointId, value) { return JSON.stringify([endpointId, value.replaceAll('\\', '/').replace(/\/+$/, '') || '/']); }
|
|
381
399
|
function canDropIntoPane(source, pane) { return source === undefined || (source.paneId !== pane.id && !isSameRemoteTransferLocation(source, { endpointId: pane.endpointId, directory: pane.path })); }
|
|
@@ -385,34 +403,34 @@ function formatBytes(value) { if (value < 1024)
|
|
|
385
403
|
return `${(value / 1024).toFixed(1)} KB`; if (value < 1024 ** 3)
|
|
386
404
|
return `${(value / 1024 ** 2).toFixed(1)} MB`; return `${(value / 1024 ** 3).toFixed(2)} GB`; }
|
|
387
405
|
function jobLabel(job, progress) { if (job.state === 'queued')
|
|
388
|
-
return
|
|
389
|
-
return
|
|
406
|
+
return t("file-transfer-workspace.waitingToTransfer"); if (job.state === 'scanning')
|
|
407
|
+
return t("file-transfer-workspace.scanningDirectories"); if (job.state === 'transferring') {
|
|
390
408
|
const seconds = Math.max(1, (Date.now() - (job.startedAt ?? Date.now())) / 1000);
|
|
391
409
|
const speed = job.transferredBytes / seconds;
|
|
392
410
|
const remaining = speed > 0 ? Math.max(0, (job.totalBytes - job.transferredBytes) / speed) : 0;
|
|
393
|
-
return `${progress.toFixed(0)}% · ${formatBytes(speed)}/s${remaining > 1 ?
|
|
411
|
+
return `${progress.toFixed(0)}% · ${formatBytes(speed)}/s${remaining > 1 ? t("file-transfer-workspace.expirySuffix", [formatDuration(remaining)]) : ''}`;
|
|
394
412
|
} if (job.state === 'completed')
|
|
395
|
-
return
|
|
396
|
-
return
|
|
413
|
+
return t("file-transfer-workspace.completedFiles", [job.completedFiles, job.skippedFiles ? t("file-transfer-workspace.skipped", [job.skippedFiles]) : '']); if (job.state === 'cancelled')
|
|
414
|
+
return t("file-transfer-workspace.cancelled"); return t("file-transfer-workspace.transferFailed"); }
|
|
397
415
|
function jobTimeLabel(job) {
|
|
398
416
|
if (job.startedAt === undefined)
|
|
399
|
-
return
|
|
417
|
+
return t("file-transfer-workspace.created", [formatClock(job.createdAt)]);
|
|
400
418
|
const end = job.completedAt ?? Date.now();
|
|
401
419
|
const elapsed = formatElapsed(Math.max(0, end - job.startedAt));
|
|
402
|
-
return job.completedAt === undefined ?
|
|
420
|
+
return job.completedAt === undefined ? t("file-transfer-workspace.executed", [elapsed]) : t("file-transfer-workspace.tookCompleted", [elapsed, formatClock(job.completedAt)]);
|
|
403
421
|
}
|
|
404
422
|
function formatClock(timestamp) { return transferClockFormatter.format(timestamp); }
|
|
405
423
|
function formatElapsed(milliseconds) {
|
|
406
424
|
const seconds = Math.max(0, Math.floor(milliseconds / 1000));
|
|
407
425
|
if (seconds < 60)
|
|
408
|
-
return
|
|
426
|
+
return t("file-transfer-workspace.seconds", [seconds]);
|
|
409
427
|
const minutes = Math.floor(seconds / 60);
|
|
410
428
|
if (minutes < 60)
|
|
411
|
-
return
|
|
412
|
-
return
|
|
429
|
+
return t("file-transfer-workspace.minutesSeconds", [minutes, String(seconds % 60).padStart(2, '0')]);
|
|
430
|
+
return t("file-transfer-workspace.hoursMinutes", [Math.floor(minutes / 60), String(minutes % 60).padStart(2, '0')]);
|
|
413
431
|
}
|
|
414
432
|
function formatDuration(seconds) { if (seconds < 60)
|
|
415
|
-
return
|
|
433
|
+
return t("file-transfer-workspace.seconds", [Math.ceil(seconds)]); const minutes = Math.ceil(seconds / 60); return minutes < 60 ? t("file-transfer-workspace.minutes", [minutes]) : t("file-transfer-workspace.hMin", [Math.floor(minutes / 60), minutes % 60]); }
|
|
416
434
|
function UpGlyph() { return _jsx("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: _jsx("path", { d: "M8 12V4m0 0L4.8 7.2M8 4l3.2 3.2" }) }); }
|
|
417
435
|
function RefreshGlyph() { return _jsx("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: _jsx("path", { d: "M12.2 5.2A5 5 0 1 0 13 9M12.2 5.2V2.5m0 2.7H9.5" }) }); }
|
|
418
436
|
function FileGlyph({ directory }) { return _jsx("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: directory ? _jsx("path", { d: "M2 4.3h4l1.2 1.4H14v6.8H2z" }) : _jsx("path", { d: "M3.2 2h6l3.6 3.6V14H3.2zm6 0v3.6h3.6" }) }); }
|