@termix-ssh/plugin-sdk 1.0.2 → 1.0.5
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/CHANGELOG.md +31 -0
- package/LICENSE +202 -0
- package/README.md +4 -2
- package/cli/commands/build.mjs +44 -19
- package/cli/commands/dev.mjs +1 -1
- package/cli/commands/migrations.mjs +2 -2
- package/cli/commands/openapi.mjs +39 -0
- package/cli/commands/validate.mjs +72 -0
- package/cli/index.mjs +3 -0
- package/cli/lib/css-classes.mjs +37 -0
- package/dist/changelog.d.ts +3 -1
- package/dist/changelog.js +12 -2
- package/dist/db.d.ts +1 -1
- package/dist/db.js +1 -1
- package/dist/ddl.js +4 -1
- package/dist/docs.d.ts +28 -0
- package/dist/docs.js +39 -0
- package/dist/frontend.d.ts +17 -0
- package/dist/frontend.js +8 -0
- package/dist/host/{chunk-XKMRKQFN.js → chunk-KOOUKYW3.js} +1 -1
- package/dist/host/{chunk-LKYAVM4T.js → chunk-OEOKIKXC.js} +18 -9
- package/dist/host/{chunk-SS43S6VI.js → chunk-VETPF5WI.js} +478 -431
- package/dist/host/core-classes.json +1 -0
- package/dist/host/{linked-server-DW5P3NLZ.js → linked-server-RWBK427T.js} +1 -1
- package/dist/host/{rbac-api-JKISXZEP.js → rbac-api-UJGGTQVA.js} +1 -1
- package/dist/host/testing-host.js +3 -3
- package/dist/host/types/src/types/credential-sidebar-preferences.d.ts +1 -1
- package/dist/host/types/src/ui/api/plugins-api.d.ts +6 -0
- package/dist/host/types/src/ui/components/docs-link.d.ts +25 -0
- package/dist/host/types/src/ui/components/panel-layout.d.ts +3 -1
- package/dist/host/types/src/ui/lib/docs.d.ts +10 -0
- package/dist/host/types/src/ui/lib/error-message.d.ts +1 -1
- package/dist/host/types/src/ui/main-axios.d.ts +1 -2
- package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +1 -0
- package/dist/host/ui.js +18 -8
- package/dist/host/{use-permissions-5CZEA3P4.js → use-permissions-P3DC7ZDR.js} +1 -1
- package/dist/host-commands.js +1 -1
- package/dist/manifest.d.ts +7 -1
- package/dist/manifest.js +48 -1
- package/dist/openapi.d.ts +43 -0
- package/dist/openapi.js +60 -0
- package/dist/testing/setup.js +1 -0
- package/package.json +22 -1
- package/schema/manifest.schema.json +21 -0
|
@@ -2,10 +2,11 @@ const __termixNoGlob = () => ({});
|
|
|
2
2
|
import {
|
|
3
3
|
hasPermission,
|
|
4
4
|
usePermissions
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KOOUKYW3.js";
|
|
6
6
|
import {
|
|
7
7
|
PRESETS,
|
|
8
8
|
SYNC_CHANGED_EVENT,
|
|
9
|
+
TRUST_TOKEN_KEY,
|
|
9
10
|
authApi,
|
|
10
11
|
buildOriginWsUrl,
|
|
11
12
|
byOrderThenId,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
usePluginStore,
|
|
39
40
|
useTabTypes,
|
|
40
41
|
websocketAuthProtocols
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-OEOKIKXC.js";
|
|
42
43
|
import {
|
|
43
44
|
__export,
|
|
44
45
|
define_import_meta_env_default
|
|
@@ -14572,9 +14573,6 @@ function resetShellBridge() {
|
|
|
14572
14573
|
setShellHosts([], false);
|
|
14573
14574
|
}
|
|
14574
14575
|
|
|
14575
|
-
// src/ui/components/panel-layout.tsx
|
|
14576
|
-
import { Children as Children5, Fragment as Fragment11, useRef as useRef28 } from "react";
|
|
14577
|
-
|
|
14578
14576
|
// node_modules/lucide-react/dist/esm/icons/index.mjs
|
|
14579
14577
|
var icons_exports = {};
|
|
14580
14578
|
__export(icons_exports, {
|
|
@@ -48949,9 +48947,295 @@ var __iconData1857 = {
|
|
|
48949
48947
|
__iconData1857.node;
|
|
48950
48948
|
var ZoomOut = createLucideIcon(__iconData1857);
|
|
48951
48949
|
|
|
48952
|
-
// src/ui/components/
|
|
48950
|
+
// src/ui/components/docs-link.tsx
|
|
48951
|
+
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
48952
|
+
|
|
48953
|
+
// packages/plugin-sdk/dist/docs.js
|
|
48954
|
+
function pluginDocsUrl(value) {
|
|
48955
|
+
if (typeof value !== "string")
|
|
48956
|
+
return null;
|
|
48957
|
+
try {
|
|
48958
|
+
const url = new URL(value.trim());
|
|
48959
|
+
if (url.protocol !== "https:")
|
|
48960
|
+
return null;
|
|
48961
|
+
return url.toString().replace(/\/$/, "");
|
|
48962
|
+
} catch {
|
|
48963
|
+
return null;
|
|
48964
|
+
}
|
|
48965
|
+
}
|
|
48966
|
+
function pluginDocsPage(base, page, anchor) {
|
|
48967
|
+
const clean = (page ?? "").replace(/^\/+|\/+$/g, "");
|
|
48968
|
+
const url = clean ? `${base}/${clean}` : base;
|
|
48969
|
+
return anchor ? `${url}#${anchor.replace(/^#/, "")}` : url;
|
|
48970
|
+
}
|
|
48971
|
+
|
|
48972
|
+
// src/ui/lib/docs-pages.json
|
|
48973
|
+
var docs_pages_default = {
|
|
48974
|
+
home: "",
|
|
48975
|
+
install: "install",
|
|
48976
|
+
updating: "install/updating",
|
|
48977
|
+
betas: "configure/betas",
|
|
48978
|
+
envVars: "configure/environment-variables",
|
|
48979
|
+
https: "configure/https",
|
|
48980
|
+
database: "configure/database",
|
|
48981
|
+
reverseProxy: "configure/reverse-proxy",
|
|
48982
|
+
desktopSync: "configure/desktop-sync",
|
|
48983
|
+
interface: "guide/interface",
|
|
48984
|
+
dashboard: "guide/dashboard",
|
|
48985
|
+
manage: "guide/manage",
|
|
48986
|
+
hosts: "guide/hosts",
|
|
48987
|
+
portKnocking: "guide/hosts#port-knocking",
|
|
48988
|
+
hostDefaults: "guide/host-defaults",
|
|
48989
|
+
credentials: "guide/credentials",
|
|
48990
|
+
sharing: "guide/sharing",
|
|
48991
|
+
account: "guide/account",
|
|
48992
|
+
accountSecurity: "guide/account#security",
|
|
48993
|
+
accountData: "guide/account#your-data",
|
|
48994
|
+
apiKeys: "guide/api-keys",
|
|
48995
|
+
commandPalette: "guide/command-palette",
|
|
48996
|
+
settings: "guide/settings",
|
|
48997
|
+
interfaceSettings: "guide/settings#interface",
|
|
48998
|
+
appearance: "guide/settings#appearance",
|
|
48999
|
+
keybindings: "guide/settings#keybindings",
|
|
49000
|
+
users: "guide/users",
|
|
49001
|
+
sessions: "guide/users#sessions",
|
|
49002
|
+
roles: "guide/roles",
|
|
49003
|
+
adminGeneral: "guide/admin-settings",
|
|
49004
|
+
branding: "guide/admin-settings#branding",
|
|
49005
|
+
adminDatabase: "guide/admin-settings#database",
|
|
49006
|
+
adminSsl: "configure/https",
|
|
49007
|
+
auditLog: "guide/audit-log",
|
|
49008
|
+
importExport: "guide/import-export",
|
|
49009
|
+
plugins: "guide/plugins",
|
|
49010
|
+
pluginCatalog: "plugins",
|
|
49011
|
+
cli: "cli",
|
|
49012
|
+
develop: "develop",
|
|
49013
|
+
communityRegistry: "develop/community-registry"
|
|
49014
|
+
};
|
|
49015
|
+
|
|
49016
|
+
// src/ui/lib/docs.ts
|
|
49017
|
+
var DOCS_URL = "https://docs.termix.site";
|
|
49018
|
+
function docsUrl(page = "home") {
|
|
49019
|
+
const path2 = docs_pages_default[page] ?? "";
|
|
49020
|
+
return path2 ? `${DOCS_URL}/${path2}` : `${DOCS_URL}/`;
|
|
49021
|
+
}
|
|
49022
|
+
|
|
49023
|
+
// src/ui/plugin-host/scope.tsx
|
|
49024
|
+
import {
|
|
49025
|
+
Component as Component2,
|
|
49026
|
+
createContext as createContext6,
|
|
49027
|
+
Suspense,
|
|
49028
|
+
useContext as useContext5
|
|
49029
|
+
} from "react";
|
|
49030
|
+
|
|
49031
|
+
// src/ui/plugin-host/host-scope.ts
|
|
49032
|
+
function isHostLike(value) {
|
|
49033
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
49034
|
+
if (!("id" in value)) return false;
|
|
49035
|
+
return "pluginSettings" in value || "ip" in value && "port" in value;
|
|
49036
|
+
}
|
|
49037
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
49038
|
+
function scopeHost(value, pluginId) {
|
|
49039
|
+
if (!isHostLike(value)) return value;
|
|
49040
|
+
const full = shellHost(value.id)?.pluginSettings ?? value.pluginSettings;
|
|
49041
|
+
let perPlugin = cache.get(value);
|
|
49042
|
+
const hit = perPlugin?.get(pluginId);
|
|
49043
|
+
if (hit && hit.source === full) return hit.scoped;
|
|
49044
|
+
const own = full?.[pluginId];
|
|
49045
|
+
const scoped = { ...value, pluginSettings: own ? { [pluginId]: own } : {} };
|
|
49046
|
+
if (!perPlugin) {
|
|
49047
|
+
perPlugin = /* @__PURE__ */ new Map();
|
|
49048
|
+
cache.set(value, perPlugin);
|
|
49049
|
+
}
|
|
49050
|
+
perPlugin.set(pluginId, { source: full, scoped });
|
|
49051
|
+
return scoped;
|
|
49052
|
+
}
|
|
49053
|
+
function scopeHostArgs(args, pluginId) {
|
|
49054
|
+
return args.map(
|
|
49055
|
+
(arg) => isHostLike(arg) ? scopeHost(arg, pluginId) : scopeHostFields(arg, pluginId)
|
|
49056
|
+
);
|
|
49057
|
+
}
|
|
49058
|
+
var HOST_FIELDS = ["host", "sshHost", "hostConfig"];
|
|
49059
|
+
function scopeHostFields(value, pluginId) {
|
|
49060
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
49061
|
+
const record = value;
|
|
49062
|
+
let next = null;
|
|
49063
|
+
for (const field of HOST_FIELDS) {
|
|
49064
|
+
if (!(field in record)) continue;
|
|
49065
|
+
const scoped = scopeHost(record[field], pluginId);
|
|
49066
|
+
if (scoped === record[field]) continue;
|
|
49067
|
+
next ??= { ...record };
|
|
49068
|
+
next[field] = scoped;
|
|
49069
|
+
}
|
|
49070
|
+
return next ?? value;
|
|
49071
|
+
}
|
|
49072
|
+
function scopeHostCallback(fn, pluginId) {
|
|
49073
|
+
if (!fn) return fn;
|
|
49074
|
+
return ((...args) => fn(...scopeHostArgs(args, pluginId)));
|
|
49075
|
+
}
|
|
49076
|
+
|
|
49077
|
+
// src/ui/plugin-host/scope.tsx
|
|
48953
49078
|
import { useTranslation } from "react-i18next";
|
|
48954
|
-
import {
|
|
49079
|
+
import { jsx as jsx29, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
49080
|
+
var PluginScopeContext = createContext6(null);
|
|
49081
|
+
function usePluginScope() {
|
|
49082
|
+
return useContext5(PluginScopeContext);
|
|
49083
|
+
}
|
|
49084
|
+
function CrashNotice({
|
|
49085
|
+
pluginId,
|
|
49086
|
+
onRetry
|
|
49087
|
+
}) {
|
|
49088
|
+
const { t } = useTranslation();
|
|
49089
|
+
const name = getPluginRecord(pluginId)?.summary.name ?? pluginId;
|
|
49090
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center justify-center gap-2 p-4 text-center text-sm text-muted-foreground", children: [
|
|
49091
|
+
/* @__PURE__ */ jsx29("span", { children: t("plugins.runtime.crashed", { name }) }),
|
|
49092
|
+
/* @__PURE__ */ jsx29(
|
|
49093
|
+
"button",
|
|
49094
|
+
{
|
|
49095
|
+
type: "button",
|
|
49096
|
+
className: "text-xs underline underline-offset-2 hover:text-foreground",
|
|
49097
|
+
onClick: onRetry,
|
|
49098
|
+
children: t("plugins.runtime.retry")
|
|
49099
|
+
}
|
|
49100
|
+
)
|
|
49101
|
+
] });
|
|
49102
|
+
}
|
|
49103
|
+
var PluginErrorBoundary = class extends Component2 {
|
|
49104
|
+
state = { error: false };
|
|
49105
|
+
static getDerivedStateFromError() {
|
|
49106
|
+
return { error: true };
|
|
49107
|
+
}
|
|
49108
|
+
componentDidCatch(error, info) {
|
|
49109
|
+
console.error(
|
|
49110
|
+
`[plugins] ${this.props.pluginId} crashed while rendering`,
|
|
49111
|
+
error,
|
|
49112
|
+
info.componentStack
|
|
49113
|
+
);
|
|
49114
|
+
}
|
|
49115
|
+
render() {
|
|
49116
|
+
if (this.state.error) {
|
|
49117
|
+
return /* @__PURE__ */ jsx29(
|
|
49118
|
+
CrashNotice,
|
|
49119
|
+
{
|
|
49120
|
+
pluginId: this.props.pluginId,
|
|
49121
|
+
onRetry: () => this.setState({ error: false })
|
|
49122
|
+
}
|
|
49123
|
+
);
|
|
49124
|
+
}
|
|
49125
|
+
return this.props.children;
|
|
49126
|
+
}
|
|
49127
|
+
};
|
|
49128
|
+
function PluginScope({
|
|
49129
|
+
pluginId,
|
|
49130
|
+
children
|
|
49131
|
+
}) {
|
|
49132
|
+
return /* @__PURE__ */ jsx29(PluginScopeContext.Provider, { value: pluginId, children: /* @__PURE__ */ jsx29(PluginErrorBoundary, { pluginId, children: /* @__PURE__ */ jsx29(Suspense, { fallback: null, children }) }) });
|
|
49133
|
+
}
|
|
49134
|
+
function withPluginScope(pluginId, Inner) {
|
|
49135
|
+
function Scoped(props) {
|
|
49136
|
+
return /* @__PURE__ */ jsx29(PluginScope, { pluginId, children: /* @__PURE__ */ jsx29(Inner, { ...scopeHostFields(props, pluginId) }) });
|
|
49137
|
+
}
|
|
49138
|
+
Scoped.displayName = `Plugin(${pluginId}:${Inner.displayName ?? Inner.name ?? "Component"})`;
|
|
49139
|
+
return Scoped;
|
|
49140
|
+
}
|
|
49141
|
+
var IconBoundary = class extends Component2 {
|
|
49142
|
+
state = { error: false };
|
|
49143
|
+
static getDerivedStateFromError() {
|
|
49144
|
+
return { error: true };
|
|
49145
|
+
}
|
|
49146
|
+
componentDidCatch(error) {
|
|
49147
|
+
console.error(`[plugins] ${this.props.pluginId} icon failed`, error);
|
|
49148
|
+
}
|
|
49149
|
+
render() {
|
|
49150
|
+
return this.state.error ? null : this.props.children;
|
|
49151
|
+
}
|
|
49152
|
+
};
|
|
49153
|
+
function withIconBoundary(pluginId, Icon2) {
|
|
49154
|
+
if (!Icon2) return void 0;
|
|
49155
|
+
function SafeIcon(props) {
|
|
49156
|
+
return /* @__PURE__ */ jsx29(IconBoundary, { pluginId, children: /* @__PURE__ */ jsx29(Icon2, { ...props }) });
|
|
49157
|
+
}
|
|
49158
|
+
SafeIcon.displayName = `PluginIcon(${pluginId})`;
|
|
49159
|
+
return SafeIcon;
|
|
49160
|
+
}
|
|
49161
|
+
function guardCallback(pluginId, fn, fallback) {
|
|
49162
|
+
if (!fn) return void 0;
|
|
49163
|
+
return (...args) => {
|
|
49164
|
+
try {
|
|
49165
|
+
return fn(...args);
|
|
49166
|
+
} catch (error) {
|
|
49167
|
+
console.error(`[plugins] ${pluginId} callback failed`, error);
|
|
49168
|
+
return fallback;
|
|
49169
|
+
}
|
|
49170
|
+
};
|
|
49171
|
+
}
|
|
49172
|
+
|
|
49173
|
+
// src/ui/components/docs-link.tsx
|
|
49174
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
49175
|
+
function usePluginDocsUrl(pluginId, page, anchor) {
|
|
49176
|
+
const { records } = usePluginStore();
|
|
49177
|
+
const base = pluginId ? records.get(pluginId)?.summary.docs : void 0;
|
|
49178
|
+
return base ? pluginDocsPage(base, page, anchor) : null;
|
|
49179
|
+
}
|
|
49180
|
+
function DocsLink({
|
|
49181
|
+
core,
|
|
49182
|
+
page,
|
|
49183
|
+
anchor,
|
|
49184
|
+
href,
|
|
49185
|
+
variant = "text",
|
|
49186
|
+
children,
|
|
49187
|
+
className
|
|
49188
|
+
}) {
|
|
49189
|
+
const { t } = useTranslation2();
|
|
49190
|
+
const pluginId = usePluginScope();
|
|
49191
|
+
const pluginUrl = usePluginDocsUrl(
|
|
49192
|
+
page !== void 0 ? pluginId : null,
|
|
49193
|
+
page,
|
|
49194
|
+
anchor
|
|
49195
|
+
);
|
|
49196
|
+
const url = href ?? (core ? withAnchor(docsUrl(core), anchor) : null) ?? pluginUrl;
|
|
49197
|
+
if (!url) return null;
|
|
49198
|
+
const label = t("common.docs");
|
|
49199
|
+
if (variant === "icon") {
|
|
49200
|
+
return /* @__PURE__ */ jsx30(
|
|
49201
|
+
"a",
|
|
49202
|
+
{
|
|
49203
|
+
href: url,
|
|
49204
|
+
target: "_blank",
|
|
49205
|
+
rel: "noopener noreferrer",
|
|
49206
|
+
title: label,
|
|
49207
|
+
"aria-label": label,
|
|
49208
|
+
className: cn(
|
|
49209
|
+
"flex size-7 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground",
|
|
49210
|
+
className
|
|
49211
|
+
),
|
|
49212
|
+
children: /* @__PURE__ */ jsx30(BookOpen, { className: "size-3.5" })
|
|
49213
|
+
}
|
|
49214
|
+
);
|
|
49215
|
+
}
|
|
49216
|
+
return /* @__PURE__ */ jsx30(
|
|
49217
|
+
"a",
|
|
49218
|
+
{
|
|
49219
|
+
href: url,
|
|
49220
|
+
target: "_blank",
|
|
49221
|
+
rel: "noopener noreferrer",
|
|
49222
|
+
className: cn(
|
|
49223
|
+
"shrink-0 text-[10px] text-accent-brand hover:underline",
|
|
49224
|
+
className
|
|
49225
|
+
),
|
|
49226
|
+
children: children ?? label
|
|
49227
|
+
}
|
|
49228
|
+
);
|
|
49229
|
+
}
|
|
49230
|
+
function withAnchor(url, anchor) {
|
|
49231
|
+
if (!anchor) return url;
|
|
49232
|
+
return `${url.split("#")[0]}#${anchor.replace(/^#/, "")}`;
|
|
49233
|
+
}
|
|
49234
|
+
|
|
49235
|
+
// src/ui/components/panel-layout.tsx
|
|
49236
|
+
import { Children as Children5, Fragment as Fragment11, useRef as useRef28 } from "react";
|
|
49237
|
+
import { useTranslation as useTranslation3 } from "react-i18next";
|
|
49238
|
+
import { Fragment as Fragment12, jsx as jsx31, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
48955
49239
|
var PANEL = {
|
|
48956
49240
|
body: "p-2.5",
|
|
48957
49241
|
gap: "gap-2",
|
|
@@ -48970,10 +49254,11 @@ function PanelShell({
|
|
|
48970
49254
|
tabs,
|
|
48971
49255
|
footer,
|
|
48972
49256
|
scroll = true,
|
|
49257
|
+
docs,
|
|
48973
49258
|
className,
|
|
48974
49259
|
children
|
|
48975
49260
|
}) {
|
|
48976
|
-
const body = /* @__PURE__ */
|
|
49261
|
+
const body = /* @__PURE__ */ jsx31(
|
|
48977
49262
|
"div",
|
|
48978
49263
|
{
|
|
48979
49264
|
className: cn(
|
|
@@ -48984,43 +49269,49 @@ function PanelShell({
|
|
|
48984
49269
|
children
|
|
48985
49270
|
}
|
|
48986
49271
|
);
|
|
48987
|
-
const bands = /* @__PURE__ */
|
|
48988
|
-
toolbar && /* @__PURE__ */
|
|
49272
|
+
const bands = /* @__PURE__ */ jsxs8(Fragment12, { children: [
|
|
49273
|
+
toolbar && /* @__PURE__ */ jsx31(
|
|
48989
49274
|
"div",
|
|
48990
49275
|
{
|
|
48991
49276
|
className: `flex shrink-0 items-center gap-2 border-b border-border ${PANEL.band}`,
|
|
48992
49277
|
children: toolbar
|
|
48993
49278
|
}
|
|
48994
49279
|
),
|
|
48995
|
-
tabs && /* @__PURE__ */
|
|
49280
|
+
tabs && /* @__PURE__ */ jsx31("div", { className: "shrink-0 border-b border-border px-1", children: tabs })
|
|
48996
49281
|
] });
|
|
48997
|
-
const foot = footer && /* @__PURE__ */
|
|
49282
|
+
const foot = footer && /* @__PURE__ */ jsx31("div", { className: "flex shrink-0 items-center gap-2 border-t border-border px-3 py-2", children: footer });
|
|
48998
49283
|
if (!chrome) {
|
|
48999
|
-
return /* @__PURE__ */
|
|
49284
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex min-h-0 flex-1 flex-col", children: [
|
|
49000
49285
|
bands,
|
|
49001
49286
|
body,
|
|
49002
49287
|
foot
|
|
49003
49288
|
] });
|
|
49004
49289
|
}
|
|
49005
|
-
return /* @__PURE__ */
|
|
49006
|
-
/* @__PURE__ */
|
|
49290
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden bg-background", children: [
|
|
49291
|
+
/* @__PURE__ */ jsxs8(
|
|
49007
49292
|
"header",
|
|
49008
49293
|
{
|
|
49009
49294
|
className: `flex ${PANEL.header} shrink-0 flex-row items-center border-b border-border`,
|
|
49010
49295
|
children: [
|
|
49011
|
-
leading && /* @__PURE__ */
|
|
49012
|
-
|
|
49013
|
-
/* @__PURE__ */
|
|
49014
|
-
|
|
49015
|
-
|
|
49016
|
-
|
|
49017
|
-
|
|
49018
|
-
|
|
49019
|
-
|
|
49020
|
-
|
|
49296
|
+
leading && /* @__PURE__ */ jsx31("div", { className: "flex h-full shrink-0 border-r border-border", children: leading }),
|
|
49297
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 items-center gap-2 px-3", children: [
|
|
49298
|
+
icon && /* @__PURE__ */ jsx31("span", { className: "shrink-0 text-accent-brand", children: icon }),
|
|
49299
|
+
/* @__PURE__ */ jsx31("span", { className: "truncate text-base font-bold tracking-tight", children: title }),
|
|
49300
|
+
status && /* @__PURE__ */ jsxs8(Fragment12, { children: [
|
|
49301
|
+
/* @__PURE__ */ jsx31(
|
|
49302
|
+
Separator4,
|
|
49303
|
+
{
|
|
49304
|
+
orientation: "vertical",
|
|
49305
|
+
className: "h-4 data-[orientation=vertical]:self-center"
|
|
49306
|
+
}
|
|
49307
|
+
),
|
|
49308
|
+
/* @__PURE__ */ jsx31("span", { className: "truncate text-[10px] font-semibold uppercase tracking-widest text-muted-foreground", children: status })
|
|
49021
49309
|
] })
|
|
49022
49310
|
] }),
|
|
49023
|
-
actions4 && /* @__PURE__ */
|
|
49311
|
+
(actions4 || docs) && /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-center gap-1 px-2", children: [
|
|
49312
|
+
actions4,
|
|
49313
|
+
docs && /* @__PURE__ */ jsx31(DocsLink, { href: docs, variant: "icon" })
|
|
49314
|
+
] })
|
|
49024
49315
|
]
|
|
49025
49316
|
}
|
|
49026
49317
|
),
|
|
@@ -49034,9 +49325,9 @@ function BackButton({
|
|
|
49034
49325
|
label,
|
|
49035
49326
|
className
|
|
49036
49327
|
}) {
|
|
49037
|
-
const { t } =
|
|
49328
|
+
const { t } = useTranslation3();
|
|
49038
49329
|
const text = label ?? t("common.back");
|
|
49039
|
-
return /* @__PURE__ */
|
|
49330
|
+
return /* @__PURE__ */ jsx31(
|
|
49040
49331
|
"button",
|
|
49041
49332
|
{
|
|
49042
49333
|
type: "button",
|
|
@@ -49047,7 +49338,7 @@ function BackButton({
|
|
|
49047
49338
|
"flex h-full w-12.5 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring",
|
|
49048
49339
|
className
|
|
49049
49340
|
),
|
|
49050
|
-
children: /* @__PURE__ */
|
|
49341
|
+
children: /* @__PURE__ */ jsx31(ArrowLeft, { className: "size-4" })
|
|
49051
49342
|
}
|
|
49052
49343
|
);
|
|
49053
49344
|
}
|
|
@@ -49063,10 +49354,10 @@ function PanelSearch({
|
|
|
49063
49354
|
inputRef,
|
|
49064
49355
|
className
|
|
49065
49356
|
}) {
|
|
49066
|
-
const { t } =
|
|
49357
|
+
const { t } = useTranslation3();
|
|
49067
49358
|
const localRef = useRef28(null);
|
|
49068
49359
|
const text = placeholder ?? t("common.search");
|
|
49069
|
-
return /* @__PURE__ */
|
|
49360
|
+
return /* @__PURE__ */ jsxs8(
|
|
49070
49361
|
"div",
|
|
49071
49362
|
{
|
|
49072
49363
|
className: cn(
|
|
@@ -49075,8 +49366,8 @@ function PanelSearch({
|
|
|
49075
49366
|
className
|
|
49076
49367
|
),
|
|
49077
49368
|
children: [
|
|
49078
|
-
/* @__PURE__ */
|
|
49079
|
-
/* @__PURE__ */
|
|
49369
|
+
/* @__PURE__ */ jsx31(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
49370
|
+
/* @__PURE__ */ jsx31(
|
|
49080
49371
|
"input",
|
|
49081
49372
|
{
|
|
49082
49373
|
ref: (el) => {
|
|
@@ -49106,7 +49397,7 @@ function PanelSearch({
|
|
|
49106
49397
|
className: "h-8 w-full min-w-0 border border-input bg-transparent pl-8 pr-7 text-xs outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30"
|
|
49107
49398
|
}
|
|
49108
49399
|
),
|
|
49109
|
-
value && /* @__PURE__ */
|
|
49400
|
+
value && /* @__PURE__ */ jsx31(
|
|
49110
49401
|
"button",
|
|
49111
49402
|
{
|
|
49112
49403
|
type: "button",
|
|
@@ -49117,7 +49408,7 @@ function PanelSearch({
|
|
|
49117
49408
|
localRef.current?.focus();
|
|
49118
49409
|
},
|
|
49119
49410
|
className: "absolute right-1.5 top-1/2 flex size-5 -translate-y-1/2 items-center justify-center text-muted-foreground hover:text-foreground",
|
|
49120
|
-
children: /* @__PURE__ */
|
|
49411
|
+
children: /* @__PURE__ */ jsx31(X, { className: "size-3" })
|
|
49121
49412
|
}
|
|
49122
49413
|
)
|
|
49123
49414
|
]
|
|
@@ -49130,14 +49421,14 @@ function Segmented({
|
|
|
49130
49421
|
options: options2,
|
|
49131
49422
|
className
|
|
49132
49423
|
}) {
|
|
49133
|
-
return /* @__PURE__ */
|
|
49424
|
+
return /* @__PURE__ */ jsx31(
|
|
49134
49425
|
"div",
|
|
49135
49426
|
{
|
|
49136
49427
|
role: "radiogroup",
|
|
49137
49428
|
className: cn("flex items-center border border-border", className),
|
|
49138
49429
|
children: options2.map((option, i) => {
|
|
49139
49430
|
const active = option.value === value;
|
|
49140
|
-
return /* @__PURE__ */
|
|
49431
|
+
return /* @__PURE__ */ jsxs8(
|
|
49141
49432
|
"button",
|
|
49142
49433
|
{
|
|
49143
49434
|
type: "button",
|
|
@@ -49153,7 +49444,7 @@ function Segmented({
|
|
|
49153
49444
|
children: [
|
|
49154
49445
|
option.icon,
|
|
49155
49446
|
option.label,
|
|
49156
|
-
option.count !== void 0 && /* @__PURE__ */
|
|
49447
|
+
option.count !== void 0 && /* @__PURE__ */ jsx31("span", { className: "text-[10px] tabular-nums opacity-60", children: option.count })
|
|
49157
49448
|
]
|
|
49158
49449
|
},
|
|
49159
49450
|
option.value
|
|
@@ -49168,35 +49459,35 @@ function ViewToggle({
|
|
|
49168
49459
|
density,
|
|
49169
49460
|
onDensity
|
|
49170
49461
|
}) {
|
|
49171
|
-
const { t } =
|
|
49172
|
-
return /* @__PURE__ */
|
|
49173
|
-
/* @__PURE__ */
|
|
49462
|
+
const { t } = useTranslation3();
|
|
49463
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center border border-border", children: [
|
|
49464
|
+
/* @__PURE__ */ jsx31(
|
|
49174
49465
|
ToggleButton,
|
|
49175
49466
|
{
|
|
49176
49467
|
active: view === "grid",
|
|
49177
49468
|
onClick: () => onView("grid"),
|
|
49178
49469
|
title: t("panel.gridView"),
|
|
49179
|
-
children: /* @__PURE__ */
|
|
49470
|
+
children: /* @__PURE__ */ jsx31(Grid3x3, { className: "size-4" })
|
|
49180
49471
|
}
|
|
49181
49472
|
),
|
|
49182
|
-
/* @__PURE__ */
|
|
49473
|
+
/* @__PURE__ */ jsx31(
|
|
49183
49474
|
ToggleButton,
|
|
49184
49475
|
{
|
|
49185
49476
|
active: view === "list",
|
|
49186
49477
|
onClick: () => onView("list"),
|
|
49187
49478
|
title: t("panel.listView"),
|
|
49188
49479
|
bordered: true,
|
|
49189
|
-
children: /* @__PURE__ */
|
|
49480
|
+
children: /* @__PURE__ */ jsx31(List2, { className: "size-4" })
|
|
49190
49481
|
}
|
|
49191
49482
|
),
|
|
49192
|
-
density && onDensity && /* @__PURE__ */
|
|
49483
|
+
density && onDensity && /* @__PURE__ */ jsx31(
|
|
49193
49484
|
ToggleButton,
|
|
49194
49485
|
{
|
|
49195
49486
|
active: density === "compact",
|
|
49196
49487
|
onClick: () => onDensity(density === "compact" ? "comfortable" : "compact"),
|
|
49197
49488
|
title: density === "compact" ? t("panel.comfortableRows") : t("panel.compactRows"),
|
|
49198
49489
|
bordered: true,
|
|
49199
|
-
children: /* @__PURE__ */
|
|
49490
|
+
children: /* @__PURE__ */ jsx31(Rows3, { className: "size-4" })
|
|
49200
49491
|
}
|
|
49201
49492
|
)
|
|
49202
49493
|
] });
|
|
@@ -49208,7 +49499,7 @@ function ToggleButton({
|
|
|
49208
49499
|
bordered,
|
|
49209
49500
|
children
|
|
49210
49501
|
}) {
|
|
49211
|
-
return /* @__PURE__ */
|
|
49502
|
+
return /* @__PURE__ */ jsx31(
|
|
49212
49503
|
"button",
|
|
49213
49504
|
{
|
|
49214
49505
|
type: "button",
|
|
@@ -49231,9 +49522,9 @@ function Facts({
|
|
|
49231
49522
|
}) {
|
|
49232
49523
|
const items = Children5.toArray(children).filter(Boolean);
|
|
49233
49524
|
if (items.length === 0) return null;
|
|
49234
|
-
return /* @__PURE__ */
|
|
49235
|
-
i > 0 && /* @__PURE__ */
|
|
49236
|
-
/* @__PURE__ */
|
|
49525
|
+
return /* @__PURE__ */ jsx31("span", { className: cn("flex min-w-0 items-center gap-2", className), children: items.map((child, i) => /* @__PURE__ */ jsxs8(Fragment11, { children: [
|
|
49526
|
+
i > 0 && /* @__PURE__ */ jsx31("span", { "aria-hidden": true, className: "h-3 w-px shrink-0 bg-border" }),
|
|
49527
|
+
/* @__PURE__ */ jsx31("span", { className: "min-w-0 truncate", children: child })
|
|
49237
49528
|
] }, i)) });
|
|
49238
49529
|
}
|
|
49239
49530
|
function GroupHeading({
|
|
@@ -49242,10 +49533,10 @@ function GroupHeading({
|
|
|
49242
49533
|
action,
|
|
49243
49534
|
className
|
|
49244
49535
|
}) {
|
|
49245
|
-
return /* @__PURE__ */
|
|
49246
|
-
/* @__PURE__ */
|
|
49247
|
-
count3 !== void 0 && /* @__PURE__ */
|
|
49248
|
-
/* @__PURE__ */
|
|
49536
|
+
return /* @__PURE__ */ jsxs8("div", { className: cn("flex items-center gap-2", className), children: [
|
|
49537
|
+
/* @__PURE__ */ jsx31("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-muted-foreground", children: title }),
|
|
49538
|
+
count3 !== void 0 && /* @__PURE__ */ jsx31("span", { className: "text-[10px] tabular-nums text-muted-foreground/60", children: count3 }),
|
|
49539
|
+
/* @__PURE__ */ jsx31("div", { className: "h-px flex-1 bg-border" }),
|
|
49249
49540
|
action
|
|
49250
49541
|
] });
|
|
49251
49542
|
}
|
|
@@ -49257,9 +49548,9 @@ var PROMPT_DESTRUCTIVE_BUTTON = "inline-flex h-7 items-center justify-center gap
|
|
|
49257
49548
|
|
|
49258
49549
|
// src/ui/components/surface/surface-scope.tsx
|
|
49259
49550
|
import {
|
|
49260
|
-
createContext as
|
|
49551
|
+
createContext as createContext7,
|
|
49261
49552
|
useCallback as useCallback18,
|
|
49262
|
-
useContext as
|
|
49553
|
+
useContext as useContext6,
|
|
49263
49554
|
useEffect as useEffect27,
|
|
49264
49555
|
useId as useId2,
|
|
49265
49556
|
useLayoutEffect as useLayoutEffect5,
|
|
@@ -49268,9 +49559,9 @@ import {
|
|
|
49268
49559
|
useState as useState25
|
|
49269
49560
|
} from "react";
|
|
49270
49561
|
import { createPortal as createPortal3 } from "react-dom";
|
|
49271
|
-
import { useTranslation as
|
|
49272
|
-
import { Fragment as Fragment13, jsx as
|
|
49273
|
-
var ScopeContext =
|
|
49562
|
+
import { useTranslation as useTranslation4 } from "react-i18next";
|
|
49563
|
+
import { Fragment as Fragment13, jsx as jsx32, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
49564
|
+
var ScopeContext = createContext7(null);
|
|
49274
49565
|
function widest(widths) {
|
|
49275
49566
|
if (widths.includes("wide")) return "wide";
|
|
49276
49567
|
return widths.some(Boolean);
|
|
@@ -49339,7 +49630,7 @@ function SurfaceScope({
|
|
|
49339
49630
|
[kind, overlay, openView, closeView, views, confirm, close]
|
|
49340
49631
|
);
|
|
49341
49632
|
const current = confirms[0];
|
|
49342
|
-
return /* @__PURE__ */
|
|
49633
|
+
return /* @__PURE__ */ jsx32(ScopeContext.Provider, { value, children: /* @__PURE__ */ jsxs9(
|
|
49343
49634
|
"div",
|
|
49344
49635
|
{
|
|
49345
49636
|
className: cn(
|
|
@@ -49348,7 +49639,7 @@ function SurfaceScope({
|
|
|
49348
49639
|
),
|
|
49349
49640
|
children: [
|
|
49350
49641
|
children,
|
|
49351
|
-
/* @__PURE__ */
|
|
49642
|
+
/* @__PURE__ */ jsx32(
|
|
49352
49643
|
"div",
|
|
49353
49644
|
{
|
|
49354
49645
|
ref: setOverlay,
|
|
@@ -49358,7 +49649,7 @@ function SurfaceScope({
|
|
|
49358
49649
|
)
|
|
49359
49650
|
}
|
|
49360
49651
|
),
|
|
49361
|
-
current && /* @__PURE__ */
|
|
49652
|
+
current && /* @__PURE__ */ jsx32(
|
|
49362
49653
|
ConfirmCard,
|
|
49363
49654
|
{
|
|
49364
49655
|
options: current,
|
|
@@ -49371,13 +49662,13 @@ function SurfaceScope({
|
|
|
49371
49662
|
) });
|
|
49372
49663
|
}
|
|
49373
49664
|
function useSurfaceKind() {
|
|
49374
|
-
return
|
|
49665
|
+
return useContext6(ScopeContext)?.kind ?? null;
|
|
49375
49666
|
}
|
|
49376
49667
|
function useSurfaceClose() {
|
|
49377
|
-
return
|
|
49668
|
+
return useContext6(ScopeContext)?.close ?? null;
|
|
49378
49669
|
}
|
|
49379
49670
|
function useConfirm() {
|
|
49380
|
-
const scope =
|
|
49671
|
+
const scope = useContext6(ScopeContext);
|
|
49381
49672
|
return useCallback18(
|
|
49382
49673
|
(options2) => {
|
|
49383
49674
|
if (scope) return scope.confirm(options2);
|
|
@@ -49391,7 +49682,7 @@ function ConfirmCard({
|
|
|
49391
49682
|
options: options2,
|
|
49392
49683
|
onSettle
|
|
49393
49684
|
}) {
|
|
49394
|
-
const { t } =
|
|
49685
|
+
const { t } = useTranslation4();
|
|
49395
49686
|
const confirmRef = useRef29(null);
|
|
49396
49687
|
const titleId = useId2();
|
|
49397
49688
|
const destructive = options2.destructive ?? true;
|
|
@@ -49416,7 +49707,7 @@ function ConfirmCard({
|
|
|
49416
49707
|
if (previous && document.contains(previous)) previous.focus();
|
|
49417
49708
|
};
|
|
49418
49709
|
}, []);
|
|
49419
|
-
return /* @__PURE__ */
|
|
49710
|
+
return /* @__PURE__ */ jsx32(
|
|
49420
49711
|
PanePrompt,
|
|
49421
49712
|
{
|
|
49422
49713
|
open: true,
|
|
@@ -49427,8 +49718,8 @@ function ConfirmCard({
|
|
|
49427
49718
|
description: options2.description,
|
|
49428
49719
|
tone: destructive ? "destructive" : "default",
|
|
49429
49720
|
onCancel: () => onSettle(false),
|
|
49430
|
-
actions: /* @__PURE__ */
|
|
49431
|
-
/* @__PURE__ */
|
|
49721
|
+
actions: /* @__PURE__ */ jsxs9(Fragment13, { children: [
|
|
49722
|
+
/* @__PURE__ */ jsx32(
|
|
49432
49723
|
"button",
|
|
49433
49724
|
{
|
|
49434
49725
|
type: "button",
|
|
@@ -49437,7 +49728,7 @@ function ConfirmCard({
|
|
|
49437
49728
|
children: options2.cancelLabel ?? t("common.cancel")
|
|
49438
49729
|
}
|
|
49439
49730
|
),
|
|
49440
|
-
/* @__PURE__ */
|
|
49731
|
+
/* @__PURE__ */ jsxs9(
|
|
49441
49732
|
"button",
|
|
49442
49733
|
{
|
|
49443
49734
|
ref: confirmRef,
|
|
@@ -49446,7 +49737,7 @@ function ConfirmCard({
|
|
|
49446
49737
|
className: destructive ? PROMPT_DESTRUCTIVE_BUTTON : PROMPT_PRIMARY_BUTTON,
|
|
49447
49738
|
children: [
|
|
49448
49739
|
options2.confirmLabel ?? (destructive ? t("common.delete") : t("common.confirm")),
|
|
49449
|
-
/* @__PURE__ */
|
|
49740
|
+
/* @__PURE__ */ jsx32("span", { "aria-hidden": true, className: "ml-1.5 opacity-60", children: "\u21B5" })
|
|
49450
49741
|
]
|
|
49451
49742
|
}
|
|
49452
49743
|
)
|
|
@@ -49473,31 +49764,31 @@ function PanePrompt({
|
|
|
49473
49764
|
const fallbackId = useId2();
|
|
49474
49765
|
if (!open) return null;
|
|
49475
49766
|
const headingId = titleId ?? fallbackId;
|
|
49476
|
-
return /* @__PURE__ */
|
|
49767
|
+
return /* @__PURE__ */ jsx32(
|
|
49477
49768
|
"div",
|
|
49478
49769
|
{
|
|
49479
49770
|
className: cn(
|
|
49480
|
-
"motion-
|
|
49481
|
-
layer === "connection" ? "z-500 bg-canvas" : "z-50 bg-background/
|
|
49771
|
+
"motion-fade-enter absolute inset-0 flex items-center justify-center overflow-y-auto p-4",
|
|
49772
|
+
layer === "connection" ? "z-500 bg-canvas" : "z-50 bg-background/85"
|
|
49482
49773
|
),
|
|
49483
49774
|
style: layer === "connection" && backgroundColor ? { backgroundColor } : void 0,
|
|
49484
49775
|
onMouseDown: (e) => {
|
|
49485
49776
|
if (e.target === e.currentTarget) onCancel?.();
|
|
49486
49777
|
},
|
|
49487
|
-
children: /* @__PURE__ */
|
|
49778
|
+
children: /* @__PURE__ */ jsxs9(
|
|
49488
49779
|
"div",
|
|
49489
49780
|
{
|
|
49490
49781
|
role,
|
|
49491
49782
|
"aria-modal": "true",
|
|
49492
49783
|
"aria-labelledby": labelledBy ?? headingId,
|
|
49493
49784
|
className: cn(
|
|
49494
|
-
"my-auto flex w-full max-w-sm flex-col border bg-popover shadow-xl",
|
|
49785
|
+
"motion-context-enter my-auto flex w-full max-w-sm flex-col border bg-popover shadow-xl",
|
|
49495
49786
|
tone === "destructive" ? "border-destructive/40" : "border-border",
|
|
49496
49787
|
className
|
|
49497
49788
|
),
|
|
49498
49789
|
children: [
|
|
49499
|
-
/* @__PURE__ */
|
|
49500
|
-
icon && /* @__PURE__ */
|
|
49790
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-2.5 px-4 pt-4", children: [
|
|
49791
|
+
icon && /* @__PURE__ */ jsx32(
|
|
49501
49792
|
"span",
|
|
49502
49793
|
{
|
|
49503
49794
|
className: cn(
|
|
@@ -49507,8 +49798,8 @@ function PanePrompt({
|
|
|
49507
49798
|
children: icon
|
|
49508
49799
|
}
|
|
49509
49800
|
),
|
|
49510
|
-
/* @__PURE__ */
|
|
49511
|
-
/* @__PURE__ */
|
|
49801
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
49802
|
+
/* @__PURE__ */ jsx32(
|
|
49512
49803
|
"p",
|
|
49513
49804
|
{
|
|
49514
49805
|
id: headingId,
|
|
@@ -49516,12 +49807,12 @@ function PanePrompt({
|
|
|
49516
49807
|
children: title
|
|
49517
49808
|
}
|
|
49518
49809
|
),
|
|
49519
|
-
description && /* @__PURE__ */
|
|
49810
|
+
description && /* @__PURE__ */ jsx32("div", { className: "text-xs leading-snug text-muted-foreground", children: description })
|
|
49520
49811
|
] })
|
|
49521
49812
|
] }),
|
|
49522
|
-
children && /* @__PURE__ */
|
|
49523
|
-
actions4 && /* @__PURE__ */
|
|
49524
|
-
!actions4 && /* @__PURE__ */
|
|
49813
|
+
children && /* @__PURE__ */ jsx32("div", { className: "px-4 pt-3", children }),
|
|
49814
|
+
actions4 && /* @__PURE__ */ jsx32("div", { className: "flex justify-end gap-2 px-4 py-3", children: actions4 }),
|
|
49815
|
+
!actions4 && /* @__PURE__ */ jsx32("div", { className: "h-4" })
|
|
49525
49816
|
]
|
|
49526
49817
|
}
|
|
49527
49818
|
)
|
|
@@ -49544,7 +49835,7 @@ function InlineView({
|
|
|
49544
49835
|
className,
|
|
49545
49836
|
children
|
|
49546
49837
|
}) {
|
|
49547
|
-
const scope =
|
|
49838
|
+
const scope = useContext6(ScopeContext);
|
|
49548
49839
|
const id = useId2();
|
|
49549
49840
|
const { openView, closeView } = scope ?? {};
|
|
49550
49841
|
useLayoutEffect5(() => {
|
|
@@ -49558,7 +49849,7 @@ function InlineView({
|
|
|
49558
49849
|
}, [onBeforeClose, onOpenChange]);
|
|
49559
49850
|
if (!open) return null;
|
|
49560
49851
|
const padded = scope?.kind === "tab" || scope?.kind === "pane";
|
|
49561
|
-
const view = /* @__PURE__ */
|
|
49852
|
+
const view = /* @__PURE__ */ jsx32(
|
|
49562
49853
|
"div",
|
|
49563
49854
|
{
|
|
49564
49855
|
className: cn(
|
|
@@ -49571,10 +49862,10 @@ function InlineView({
|
|
|
49571
49862
|
void requestClose();
|
|
49572
49863
|
}
|
|
49573
49864
|
},
|
|
49574
|
-
children: /* @__PURE__ */
|
|
49865
|
+
children: /* @__PURE__ */ jsx32(
|
|
49575
49866
|
PanelShell,
|
|
49576
49867
|
{
|
|
49577
|
-
leading: /* @__PURE__ */
|
|
49868
|
+
leading: /* @__PURE__ */ jsx32(BackButton, { onClick: () => void requestClose() }),
|
|
49578
49869
|
icon,
|
|
49579
49870
|
title,
|
|
49580
49871
|
status,
|
|
@@ -49582,7 +49873,7 @@ function InlineView({
|
|
|
49582
49873
|
toolbar,
|
|
49583
49874
|
footer,
|
|
49584
49875
|
scroll,
|
|
49585
|
-
children: bare ? children : /* @__PURE__ */
|
|
49876
|
+
children: bare ? children : /* @__PURE__ */ jsx32(
|
|
49586
49877
|
"div",
|
|
49587
49878
|
{
|
|
49588
49879
|
className: cn(
|
|
@@ -49601,7 +49892,7 @@ function InlineView({
|
|
|
49601
49892
|
if (scope?.overlay) return createPortal3(view, scope.overlay);
|
|
49602
49893
|
if (scope) return null;
|
|
49603
49894
|
return createPortal3(
|
|
49604
|
-
/* @__PURE__ */
|
|
49895
|
+
/* @__PURE__ */ jsx32("div", { className: "fixed inset-0 z-50 bg-background", children: view }),
|
|
49605
49896
|
document.body
|
|
49606
49897
|
);
|
|
49607
49898
|
}
|
|
@@ -50183,12 +50474,8 @@ var en_default = {
|
|
|
50183
50474
|
offline: "Offline",
|
|
50184
50475
|
unknown: "Unknown",
|
|
50185
50476
|
continue: "Continue",
|
|
50186
|
-
maintenance: "Maintenance",
|
|
50187
|
-
degraded: "Degraded",
|
|
50188
50477
|
error: "Error",
|
|
50189
|
-
warning: "Warning",
|
|
50190
50478
|
unsavedChanges: "Unsaved changes",
|
|
50191
|
-
dismiss: "Dismiss",
|
|
50192
50479
|
more: "More",
|
|
50193
50480
|
loading: "Loading...",
|
|
50194
50481
|
host: "Host",
|
|
@@ -50198,15 +50485,7 @@ var en_default = {
|
|
|
50198
50485
|
connect: "Connect",
|
|
50199
50486
|
copied: "Copied",
|
|
50200
50487
|
connecting: "Connecting...",
|
|
50201
|
-
updateAvailable: "Update Available",
|
|
50202
|
-
appName: "Termix",
|
|
50203
50488
|
openInNewTab: "Open in New Tab",
|
|
50204
|
-
noReleases: "No Releases",
|
|
50205
|
-
updatesAndReleases: "Updates & Releases",
|
|
50206
|
-
newVersionAvailable: "A new version ({{version}}) is available.",
|
|
50207
|
-
failedToFetchUpdateInfo: "Failed to fetch update information",
|
|
50208
|
-
preRelease: "Pre-release",
|
|
50209
|
-
noReleasesFound: "No releases found.",
|
|
50210
50489
|
cancel: "Cancel",
|
|
50211
50490
|
username: "Username",
|
|
50212
50491
|
login: "Login",
|
|
@@ -50221,15 +50500,10 @@ var en_default = {
|
|
|
50221
50500
|
rename: "Rename",
|
|
50222
50501
|
edit: "Edit",
|
|
50223
50502
|
confirm: "Confirm",
|
|
50224
|
-
no: "No",
|
|
50225
|
-
or: "OR",
|
|
50226
50503
|
next: "Next",
|
|
50227
50504
|
previous: "Previous",
|
|
50228
50505
|
refresh: "Refresh",
|
|
50229
50506
|
language: "Language",
|
|
50230
|
-
checking: "Checking...",
|
|
50231
|
-
checkingDatabase: "Checking database connection...",
|
|
50232
|
-
checkingAuthentication: "Checking authentication...",
|
|
50233
50507
|
backendReconnected: "Server connection restored",
|
|
50234
50508
|
connectionDegraded: "Server connection lost, recovering\u2026",
|
|
50235
50509
|
reload: "Reload",
|
|
@@ -50238,12 +50512,6 @@ var en_default = {
|
|
|
50238
50512
|
copyFailed: "Failed to copy to clipboard",
|
|
50239
50513
|
maximize: "Maximize",
|
|
50240
50514
|
restore: "Restore",
|
|
50241
|
-
of: "of",
|
|
50242
|
-
saved: "Saved",
|
|
50243
|
-
deleted: "Deleted",
|
|
50244
|
-
deleteFailed: "Failed to delete",
|
|
50245
|
-
saveFailed: "Failed to save",
|
|
50246
|
-
required: "Required",
|
|
50247
50515
|
remove: "Remove",
|
|
50248
50516
|
add: "Add",
|
|
50249
50517
|
update: "Update",
|
|
@@ -50252,7 +50520,8 @@ var en_default = {
|
|
|
50252
50520
|
mobileSidebarDescription: "Displays the mobile sidebar.",
|
|
50253
50521
|
toggleSidebar: "Toggle Sidebar",
|
|
50254
50522
|
search: "Search...",
|
|
50255
|
-
new: "New"
|
|
50523
|
+
new: "New",
|
|
50524
|
+
docs: "Docs"
|
|
50256
50525
|
},
|
|
50257
50526
|
onboarding: {
|
|
50258
50527
|
stepCounter: "Step {{current}} of {{total}}",
|
|
@@ -50264,8 +50533,8 @@ var en_default = {
|
|
|
50264
50533
|
skip: "Skip setup",
|
|
50265
50534
|
next: "Next",
|
|
50266
50535
|
finish: "Done",
|
|
50267
|
-
pluginsTitle: "Choose your
|
|
50268
|
-
pluginsIntro: "Pick the
|
|
50536
|
+
pluginsTitle: "Choose your plugins",
|
|
50537
|
+
pluginsIntro: "Pick the plugins to keep. The recommended ones cover what most people need.",
|
|
50269
50538
|
pluginsUpgradeNote: "Everything you use now is kept as it is. Turn off or remove what you do not need.",
|
|
50270
50539
|
pluginsRemoveNote: "Plugins set to Remove are deleted from this server, with their data, when you continue. You can install any of them again at any time from the Plugins tab (this needs an internet connection). Pick Off to keep a plugin installed but turned off.",
|
|
50271
50540
|
pluginsUseRecommended: "Recommended",
|
|
@@ -50296,24 +50565,17 @@ var en_default = {
|
|
|
50296
50565
|
desktopLocalBody: "Everything is stored here. Nothing to set up.",
|
|
50297
50566
|
desktopLinkTitle: "With my Termix server",
|
|
50298
50567
|
desktopLinkBody: "Sign in to your server to use the same hosts and settings on every device.",
|
|
50299
|
-
desktopLinked: "Linked to {{server}}"
|
|
50568
|
+
desktopLinked: "Linked to {{server}}",
|
|
50569
|
+
pluginsDocsLink: "Read about each one"
|
|
50300
50570
|
},
|
|
50301
50571
|
nav: {
|
|
50302
50572
|
home: "Home",
|
|
50303
50573
|
terminal: "Terminal",
|
|
50304
|
-
fileManager: "File Manager",
|
|
50305
|
-
serverStats: "Host Metrics",
|
|
50306
|
-
admin: "Admin",
|
|
50307
|
-
userProfile: "User Profile",
|
|
50308
|
-
confirmClose: "Close this active session?",
|
|
50309
50574
|
close: "Close",
|
|
50310
|
-
cancel: "Cancel",
|
|
50311
|
-
sshManager: "SSH Manager",
|
|
50312
50575
|
hostTabTitle: "{{username}}@{{ip}}:{{port}}",
|
|
50313
50576
|
copyPassword: "Copy Password",
|
|
50314
50577
|
copySudoPassword: "Copy Sudo Password",
|
|
50315
50578
|
passwordCopied: "Password copied to clipboard",
|
|
50316
|
-
noPasswordAvailable: "No password available",
|
|
50317
50579
|
failedToCopyPassword: "Failed to copy password",
|
|
50318
50580
|
refreshTab: "Refresh connection",
|
|
50319
50581
|
renameTab: "Rename tab",
|
|
@@ -50324,13 +50586,7 @@ var en_default = {
|
|
|
50324
50586
|
openInRightDock: "Open in right dock",
|
|
50325
50587
|
closeRightDock: "Close right dock",
|
|
50326
50588
|
toggleRightDock: "Toggle right dock",
|
|
50327
|
-
multiPanelHintTitle: "Work with more than one panel",
|
|
50328
|
-
multiPanelHintBody: "Keep this panel open while the sidebar is used for something else. Two ways to move it:",
|
|
50329
|
-
multiPanelHintTabHow: "Ctrl+click its rail icon, or use the button in this header.",
|
|
50330
|
-
multiPanelHintDockHow: "Right-click its rail icon, or use the panel icon in the tab bar.",
|
|
50331
|
-
sidebarSettings: "Sidebar Settings...",
|
|
50332
50589
|
hosts: "Hosts",
|
|
50333
|
-
hostManager: "Host Manager",
|
|
50334
50590
|
credentials: "Credentials",
|
|
50335
50591
|
connections: "Connections",
|
|
50336
50592
|
keepSideMenuOpen: "Keep Menu Open",
|
|
@@ -50702,8 +50958,8 @@ var en_default = {
|
|
|
50702
50958
|
showPinIconDesc: "Show a pin next to pinned hosts.",
|
|
50703
50959
|
showSharedBadge: "Shared badge",
|
|
50704
50960
|
showSharedBadgeDesc: "Show a badge on hosts shared with you.",
|
|
50705
|
-
showBadges: "
|
|
50706
|
-
showBadgesDesc: "Show badges that
|
|
50961
|
+
showBadges: "Plugin badges",
|
|
50962
|
+
showBadgesDesc: "Show badges that plugins add next to the host name.",
|
|
50707
50963
|
hostClickBehavior: "Clicking a host",
|
|
50708
50964
|
hostClickBehaviorDesc: 'What happens when you click a host that already has an open tab. Ctrl/Cmd click, middle click, or "Open in new tab" always start a new one.',
|
|
50709
50965
|
hostClickNewTab: "Always open a new tab",
|
|
@@ -50776,7 +51032,7 @@ var en_default = {
|
|
|
50776
51032
|
groupTags: "Tags & pin",
|
|
50777
51033
|
groupProxy: "Proxy",
|
|
50778
51034
|
groupJumpHosts: "Jump hosts",
|
|
50779
|
-
groupFeatureFlags: "
|
|
51035
|
+
groupFeatureFlags: "Plugin settings",
|
|
50780
51036
|
groupAdvanced: "Advanced config",
|
|
50781
51037
|
preview: "Preview",
|
|
50782
51038
|
moreHosts: "... {{count}} more hosts",
|
|
@@ -50793,7 +51049,7 @@ var en_default = {
|
|
|
50793
51049
|
failedToDeleteCredential2: "Failed to delete credential",
|
|
50794
51050
|
noFolderOption: "(No folder)",
|
|
50795
51051
|
nSelected: "{{count}} selected",
|
|
50796
|
-
featuresMenu: "
|
|
51052
|
+
featuresMenu: "Plugins",
|
|
50797
51053
|
moveMenu: "Move",
|
|
50798
51054
|
connectSelected: "Connect",
|
|
50799
51055
|
cancelSelection: "Cancel",
|
|
@@ -50809,6 +51065,7 @@ var en_default = {
|
|
|
50809
51065
|
noHostsYet: "No hosts yet",
|
|
50810
51066
|
noHostsYetHint: "Add a server to open terminals, browse files and see metrics.",
|
|
50811
51067
|
noHostsMatchSearch: "No hosts match your search",
|
|
51068
|
+
noHostSelected: "Pick a host to open this.",
|
|
50812
51069
|
searchHosts: "Search hosts...",
|
|
50813
51070
|
sortHosts: "Sort Hosts",
|
|
50814
51071
|
sortDefault: "Default Order",
|
|
@@ -50934,12 +51191,12 @@ var en_default = {
|
|
|
50934
51191
|
authFieldsAfterSave: "Save the host first, then fill in these fields.",
|
|
50935
51192
|
enablePluginFeature: "Enable {{name}}",
|
|
50936
51193
|
disablePluginFeature: "Disable {{name}}",
|
|
50937
|
-
filterFeaturesGroup: "
|
|
51194
|
+
filterFeaturesGroup: "Plugins",
|
|
50938
51195
|
localOnly: "Keep on this device only",
|
|
50939
51196
|
localOnlyDesc: "This host is not sent to the server and does not appear on your other devices.",
|
|
50940
51197
|
folderLocalOnly: "Keep on this device only",
|
|
50941
51198
|
folderLocalOnlyDesc: "This folder and every host in it stay on this device and are not sent to the server.",
|
|
50942
|
-
sudoPasswordDesc: "Used when the terminal fills a sudo prompt, and by
|
|
51199
|
+
sudoPasswordDesc: "Used when the terminal fills a sudo prompt, and by plugins that run commands with sudo.",
|
|
50943
51200
|
editorCancel: "Cancel",
|
|
50944
51201
|
editorSaving: "Saving...",
|
|
50945
51202
|
editorUpdate: "Update Host",
|
|
@@ -50956,25 +51213,18 @@ var en_default = {
|
|
|
50956
51213
|
quickActions: "Quick Actions",
|
|
50957
51214
|
navigation: "Navigation",
|
|
50958
51215
|
orShortcut: "or",
|
|
50959
|
-
hostManager: "Host Manager",
|
|
50960
|
-
hostManagerDesc: "Manage, add, or edit hosts",
|
|
50961
51216
|
addNewHost: "Add New Host",
|
|
50962
|
-
addNewHostDesc: "Register a new host",
|
|
50963
51217
|
adminSettings: "Admin Settings",
|
|
50964
|
-
adminSettingsDesc: "Configure system preferences and users",
|
|
50965
|
-
userProfile: "User Profile",
|
|
50966
|
-
userProfileDesc: "Manage your account and preferences",
|
|
50967
51218
|
addCredential: "Add Credential",
|
|
50968
|
-
addCredentialDesc: "Store SSH keys or passwords",
|
|
50969
51219
|
recentActivity: "Recent Activity",
|
|
50970
51220
|
serversAndHosts: "Servers & Hosts",
|
|
50971
51221
|
noHostsFound: 'No hosts found matching "{{search}}"',
|
|
50972
51222
|
links: "Links",
|
|
50973
51223
|
navigate: "Navigate",
|
|
50974
51224
|
select: "Select",
|
|
50975
|
-
toggleWith: "Toggle with",
|
|
50976
51225
|
pluginActions: "More actions",
|
|
50977
|
-
noTargetTab: "No terminal tab is open"
|
|
51226
|
+
noTargetTab: "No terminal tab is open",
|
|
51227
|
+
documentation: "Documentation"
|
|
50978
51228
|
},
|
|
50979
51229
|
splitScreen: {
|
|
50980
51230
|
title: "Split screen",
|
|
@@ -51006,7 +51256,6 @@ var en_default = {
|
|
|
51006
51256
|
unsplit: "Unsplit",
|
|
51007
51257
|
layouts: "Layouts",
|
|
51008
51258
|
applyLayout: "Change layout",
|
|
51009
|
-
newSplit: "New split",
|
|
51010
51259
|
maxPanes: "A split can hold up to {{count}} panes",
|
|
51011
51260
|
dropSplit: "Drop to split",
|
|
51012
51261
|
dropHere: "Drop to show here",
|
|
@@ -51033,16 +51282,10 @@ var en_default = {
|
|
|
51033
51282
|
connectedFor: "Connected for {{duration}}",
|
|
51034
51283
|
connected: "Connected",
|
|
51035
51284
|
disconnected: "Disconnected",
|
|
51036
|
-
closeTab: "Close tab",
|
|
51037
|
-
closeConnection: "Close connection",
|
|
51038
|
-
forgetTab: "Forget",
|
|
51039
|
-
removeBackground: "Remove",
|
|
51040
51285
|
reconnect: "Reconnect",
|
|
51041
|
-
reopenTab: "Reopen",
|
|
51042
51286
|
sectionOpen: "Open",
|
|
51043
51287
|
sectionBackground: "Background",
|
|
51044
51288
|
backgroundDesc: "Sessions persist for {{minutes}} minutes after disconnect and can be reconnected.",
|
|
51045
|
-
persisted: "Persisted in background",
|
|
51046
51289
|
expiresIn: "Expires in {{duration}}",
|
|
51047
51290
|
search: "Search connections...",
|
|
51048
51291
|
noSearchResults: "No connections match your search",
|
|
@@ -51082,7 +51325,7 @@ var en_default = {
|
|
|
51082
51325
|
empty: "No cards. Use Add below to place cards."
|
|
51083
51326
|
},
|
|
51084
51327
|
auth: {
|
|
51085
|
-
tagline: "Self-hosted, plugin-based server management",
|
|
51328
|
+
tagline: "Self-hosted, plugin-based server management.",
|
|
51086
51329
|
loginTitle: "Welcome back",
|
|
51087
51330
|
registerTitle: "Create Account",
|
|
51088
51331
|
forgotPassword: "Forgot Password?",
|
|
@@ -51104,36 +51347,22 @@ var en_default = {
|
|
|
51104
51347
|
sshKeyPasswordDescription: "If your SSH key is encrypted, enter the passphrase here.",
|
|
51105
51348
|
passphraseRequired: "Passphrase Required",
|
|
51106
51349
|
passphraseRequiredDescription: "The SSH key is encrypted. Please enter the passphrase to unlock it.",
|
|
51107
|
-
back: "Back",
|
|
51108
|
-
firstUser: "First User",
|
|
51109
|
-
firstUserMessage: "You are the first user and will be made an admin. You can view admin settings in the sidebar user dropdown. If you think this is a mistake, check the docker logs, or create a GitHub issue.",
|
|
51110
51350
|
external: "External",
|
|
51111
51351
|
loginWithExternal: "Login with External Provider",
|
|
51112
51352
|
loginWithExternalDesc: "Login using your configured external identity provider",
|
|
51113
|
-
externalNotSupportedInElectron: "External sign-in is not supported in the desktop app yet. Please use the web version.",
|
|
51114
51353
|
loginWithProvider: "Login with {{name}}",
|
|
51115
|
-
orContinueWith: "or continue with",
|
|
51116
51354
|
resetPasswordButton: "Reset Password",
|
|
51117
51355
|
sendResetCode: "Send Reset Code",
|
|
51118
51356
|
resetCodeDesc: "Enter your username to receive a password reset code. The code will be logged in the docker container logs.",
|
|
51119
51357
|
resetCode: "Reset Code",
|
|
51120
51358
|
verifyCodeButton: "Verify Code",
|
|
51121
|
-
enterResetCode: "Enter the 6-digit code from the docker container logs for user:",
|
|
51122
51359
|
newPassword: "New Password",
|
|
51123
51360
|
confirmNewPassword: "Confirm Password",
|
|
51124
|
-
enterNewPassword: "Enter your new password for user:",
|
|
51125
51361
|
signUp: "Sign Up",
|
|
51126
|
-
desktopApp: "Desktop App",
|
|
51127
|
-
loggingInToDesktopApp: "Logging in to the desktop app",
|
|
51128
51362
|
loadingServer: "Loading server...",
|
|
51129
|
-
dataLossWarning: "Resetting your password this way will delete all your saved SSH hosts, credentials, and other encrypted data. This action cannot be undone. Only use this if you have forgotten your password and are not logged in.",
|
|
51130
|
-
authenticationDisabled: "Authentication Disabled",
|
|
51131
|
-
authenticationDisabledDesc: "All authentication methods are currently disabled. Please contact your administrator.",
|
|
51132
|
-
passwordLoginDisabledDesc: "Password login is disabled. Use a passkey or an external authentication provider.",
|
|
51133
|
-
attemptsRemaining: "{{count}} attempts remaining",
|
|
51134
|
-
confirmResetDataWipe: "This account has not logged in since the encryption upgrade, so its stored data cannot be recovered without the old password. Resetting will permanently delete its hosts, credentials and snippets. Continue?",
|
|
51135
51363
|
password: "Password",
|
|
51136
51364
|
secondFactorUnavailable: "Your account uses a second factor that is not available right now. Contact an admin to reset it.",
|
|
51365
|
+
externalLoginRequired: "This account signs in through single sign-on. Use that button to sign in.",
|
|
51137
51366
|
secondFactorNoUI: "This second factor cannot be shown on this screen. Contact an admin.",
|
|
51138
51367
|
serverAuthentication: "Server sign-in",
|
|
51139
51368
|
minChars: "min. {{min}} characters",
|
|
@@ -51163,6 +51392,8 @@ var en_default = {
|
|
|
51163
51392
|
databaseConnection: "Could not connect to the database",
|
|
51164
51393
|
embeddedServerFailed: "Termix's local server could not start",
|
|
51165
51394
|
unknownError: "Unknown error",
|
|
51395
|
+
syncedHostMissing: "The synced host does not exist on the linked server",
|
|
51396
|
+
linkedServerUnreachable: "The linked server is not reachable",
|
|
51166
51397
|
loginFailed: "Login failed",
|
|
51167
51398
|
failedPasswordReset: "Failed to initiate password reset",
|
|
51168
51399
|
failedVerifyCode: "Failed to verify reset code",
|
|
@@ -51176,12 +51407,7 @@ var en_default = {
|
|
|
51176
51407
|
requiredField: "This field is required",
|
|
51177
51408
|
minLength: "Minimum length is {{min}}",
|
|
51178
51409
|
passwordMismatch: "Passwords do not match",
|
|
51179
|
-
passwordLoginDisabled: "Username/password login is currently disabled",
|
|
51180
51410
|
sessionExpired: "Session expired - please log in again",
|
|
51181
|
-
totpRateLimited: "Rate limited: Too many TOTP verification attempts. Please try again later.",
|
|
51182
|
-
totpRateLimitedWithTime: "Rate limited: Too many TOTP verification attempts. Please wait {{time}} seconds before trying again.",
|
|
51183
|
-
resetCodeRateLimited: "Rate limited: Too many verification attempts. Please try again later.",
|
|
51184
|
-
resetCodeRateLimitedWithTime: "Rate limited: Too many verification attempts. Please wait {{time}} seconds before trying again.",
|
|
51185
51411
|
authTokenSaveFailed: "Failed to save authentication token",
|
|
51186
51412
|
authTokenMissing: "The server did not return a new authentication token. Please sign in again.",
|
|
51187
51413
|
failedToLoadServer: "Failed to load server",
|
|
@@ -51201,7 +51427,6 @@ var en_default = {
|
|
|
51201
51427
|
registrationSuccess: "Registration successful"
|
|
51202
51428
|
},
|
|
51203
51429
|
placeholders: {
|
|
51204
|
-
language: "Language",
|
|
51205
51430
|
keyPassword: "key password",
|
|
51206
51431
|
pastePrivateKey: "Paste your private key here...",
|
|
51207
51432
|
enterPassword: "Enter your password",
|
|
@@ -51214,7 +51439,6 @@ var en_default = {
|
|
|
51214
51439
|
},
|
|
51215
51440
|
dashboard: {
|
|
51216
51441
|
title: "Dashboard",
|
|
51217
|
-
loading: "Loading dashboard...",
|
|
51218
51442
|
github: "GitHub",
|
|
51219
51443
|
reportBug: "Report a bug",
|
|
51220
51444
|
discord: "Discord",
|
|
@@ -51222,7 +51446,6 @@ var en_default = {
|
|
|
51222
51446
|
donate: "Donate",
|
|
51223
51447
|
serverOverview: "Server Overview",
|
|
51224
51448
|
version: "Version",
|
|
51225
|
-
upToDate: "Up to Date",
|
|
51226
51449
|
updateAvailable: "Update Available",
|
|
51227
51450
|
beta: "Beta",
|
|
51228
51451
|
uptime: "Uptime",
|
|
@@ -51233,7 +51456,6 @@ var en_default = {
|
|
|
51233
51456
|
totalCredentials: "Total Credentials",
|
|
51234
51457
|
recentActivity: "Recent Activity",
|
|
51235
51458
|
reset: "Reset",
|
|
51236
|
-
loadingRecentActivity: "Loading recent activity...",
|
|
51237
51459
|
noRecentActivity: "No recent activity",
|
|
51238
51460
|
quickActions: "Quick Actions",
|
|
51239
51461
|
addHost: "Add Host",
|
|
@@ -51241,48 +51463,21 @@ var en_default = {
|
|
|
51241
51463
|
adminSettings: "Admin Settings",
|
|
51242
51464
|
userProfile: "User Profile",
|
|
51243
51465
|
serverStats: "Server Stats",
|
|
51244
|
-
loadingServerStats: "Loading server stats...",
|
|
51245
|
-
noServerData: "No server data available",
|
|
51246
51466
|
customizeLayout: "Customize Dashboard",
|
|
51247
|
-
|
|
51248
|
-
enableDisableCards: "Enable/Disable Cards",
|
|
51249
|
-
resetLayout: "Reset to Default",
|
|
51250
|
-
serverOverviewCard: "Server Overview",
|
|
51251
|
-
recentActivityCard: "Recent Activity",
|
|
51252
|
-
quickActionsCard: "Quick Actions",
|
|
51253
|
-
serverStatsCard: "Server Stats",
|
|
51254
|
-
panelMain: "Main",
|
|
51255
|
-
panelSide: "Side",
|
|
51256
|
-
justNow: "just now",
|
|
51257
|
-
activityFileManager: "File manager"
|
|
51258
|
-
},
|
|
51259
|
-
donation: {
|
|
51260
|
-
title: "Enjoying Termix?",
|
|
51261
|
-
body: "Termix is free and open source, built and maintained by a two-person team in our spare time. If it's replaced a commercial tool you'd otherwise be paying for, a donation helps cover hosting costs and keeps development going. As of now, donations are crypto only.",
|
|
51262
|
-
milestones: "Donations also help fund the time to research and learn what's needed to build features like SAML and Kubernetes support. See the progress on the donate page.",
|
|
51263
|
-
cta: "Donate",
|
|
51264
|
-
dismiss: "Maybe later"
|
|
51467
|
+
justNow: "just now"
|
|
51265
51468
|
},
|
|
51266
51469
|
dashboardTab: {
|
|
51267
51470
|
stable: "STABLE",
|
|
51268
|
-
hostsOnline: "Hosts Online",
|
|
51269
51471
|
registerNewServer: "Register a new server",
|
|
51270
51472
|
storeSshKeysOrPasswords: "Store SSH keys or passwords",
|
|
51271
51473
|
manageUsersAndRoles: "Manage users and roles",
|
|
51272
51474
|
manageYourAccount: "Manage your account",
|
|
51273
51475
|
hostStatus: "Host Status",
|
|
51274
51476
|
noHostsConfigured: "No hosts configured",
|
|
51275
|
-
online: "ONLINE",
|
|
51276
|
-
offline: "OFFLINE",
|
|
51277
51477
|
checking: "CHECKING",
|
|
51278
|
-
onlineLower: "Online",
|
|
51279
|
-
add: "Add:",
|
|
51280
51478
|
commandPalette: "Command Palette",
|
|
51281
51479
|
done: "Done",
|
|
51282
|
-
editModeInstructions: "Drag cards to reorder. Drag the column divider to resize columns. Drag the bottom edge of a card to change its height. Use the trash button to remove a card.",
|
|
51283
|
-
empty: "Empty",
|
|
51284
51480
|
clear: "Clear",
|
|
51285
|
-
viewServerDetails: "View server details",
|
|
51286
51481
|
dragToResizeColumns: "Drag to resize columns",
|
|
51287
51482
|
hostsAvailable: "Hosts Available",
|
|
51288
51483
|
removeSection: "Remove section",
|
|
@@ -51434,7 +51629,6 @@ var en_default = {
|
|
|
51434
51629
|
noCustomRoles: "No custom roles defined",
|
|
51435
51630
|
removeRoleFailed: "Failed to remove role",
|
|
51436
51631
|
assignRoleFailed: "Failed to assign role",
|
|
51437
|
-
deleteRoleFailed: "Failed to delete role",
|
|
51438
51632
|
userAdminAccess: "Administrator",
|
|
51439
51633
|
userAdminAccessDesc: "Full access to all admin settings",
|
|
51440
51634
|
userRoles: "Roles",
|
|
@@ -51457,7 +51651,6 @@ var en_default = {
|
|
|
51457
51651
|
createUserPassword: "Password",
|
|
51458
51652
|
createUserPasswordHint: "Minimum 6 characters.",
|
|
51459
51653
|
createUserEnterUsername: "Enter username",
|
|
51460
|
-
createUserEnterPassword: "Enter password",
|
|
51461
51654
|
createUserSubmit: "Create User",
|
|
51462
51655
|
editUserTitle: "Manage User: {{username}}",
|
|
51463
51656
|
editUserDesc: "Edit roles, admin status, sessions, and account settings.",
|
|
@@ -51488,7 +51681,6 @@ var en_default = {
|
|
|
51488
51681
|
unlinkAccountInProgress: "Unlinking...",
|
|
51489
51682
|
unlinkAccountSuccess: "External sign-in unlinked",
|
|
51490
51683
|
unlinkAccountFailed: "Failed to unlink external sign-in",
|
|
51491
|
-
saving: "Saving...",
|
|
51492
51684
|
updateRegistrationFailed: "Failed to update registration setting",
|
|
51493
51685
|
updatePasswordLoginFailed: "Failed to update password login setting",
|
|
51494
51686
|
updateSecondFactorAfterExternalLoginFailed: "Failed to update second factor setting",
|
|
@@ -51570,7 +51762,6 @@ var en_default = {
|
|
|
51570
51762
|
importFailed: "Import failed: {{error}}",
|
|
51571
51763
|
importError: "Database import failed",
|
|
51572
51764
|
sectionHostDefaults: "Host Defaults",
|
|
51573
|
-
minutes: "minutes",
|
|
51574
51765
|
rolePermissions: {
|
|
51575
51766
|
count: "{{count}} permissions",
|
|
51576
51767
|
editAction: "Edit permissions",
|
|
@@ -51579,7 +51770,7 @@ var en_default = {
|
|
|
51579
51770
|
saveError: "Failed to save role permissions",
|
|
51580
51771
|
save: "Save",
|
|
51581
51772
|
saving: "Saving...",
|
|
51582
|
-
pluginDisabled: "
|
|
51773
|
+
pluginDisabled: "Plugin disabled",
|
|
51583
51774
|
groups: {
|
|
51584
51775
|
hosts: "Hosts",
|
|
51585
51776
|
credentials: "Credentials",
|
|
@@ -51622,7 +51813,6 @@ var en_default = {
|
|
|
51622
51813
|
hostLabel: "Host",
|
|
51623
51814
|
hostPlaceholder: "192.168.1.1 or example.com",
|
|
51624
51815
|
portLabel: "Port",
|
|
51625
|
-
portPlaceholder: "22",
|
|
51626
51816
|
usernameLabel: "Username",
|
|
51627
51817
|
usernamePlaceholder: "username",
|
|
51628
51818
|
authLabel: "Auth",
|
|
@@ -51640,7 +51830,6 @@ var en_default = {
|
|
|
51640
51830
|
noTarget: "Nothing installed can connect to this host type"
|
|
51641
51831
|
},
|
|
51642
51832
|
keybindings: {
|
|
51643
|
-
title: "Keyboard Shortcuts",
|
|
51644
51833
|
description: "Bind keys to actions in the terminal and the app, or change the built-in shortcuts.",
|
|
51645
51834
|
defaultsHeading: "Built-in Shortcuts",
|
|
51646
51835
|
fixedHeading: "App Shortcuts",
|
|
@@ -51666,7 +51855,6 @@ var en_default = {
|
|
|
51666
51855
|
customize: "Customize",
|
|
51667
51856
|
resetToDefault: "Reset to default",
|
|
51668
51857
|
resetAllToDefaults: "Reset all to defaults",
|
|
51669
|
-
close: "Close",
|
|
51670
51858
|
cancel: "Cancel",
|
|
51671
51859
|
saveBinding: "Save Shortcut",
|
|
51672
51860
|
saveError: "Failed to save keyboard shortcuts",
|
|
@@ -51737,7 +51925,6 @@ var en_default = {
|
|
|
51737
51925
|
cliLearnMore: "Learn More",
|
|
51738
51926
|
deleteAccount: "Delete Account",
|
|
51739
51927
|
deleteAccountDescription: "Permanently delete your account",
|
|
51740
|
-
changeServerDescription: "Switch to a different Termix backend server",
|
|
51741
51928
|
deleteButton: "Delete",
|
|
51742
51929
|
deleteAccountPermanent: "This action is permanent and cannot be undone.",
|
|
51743
51930
|
deleteAccountWarning: "All sessions, hosts, credentials, and settings will be permanently deleted.",
|
|
@@ -51751,8 +51938,6 @@ var en_default = {
|
|
|
51751
51938
|
keyboardShortcuts: "Keyboard Shortcuts",
|
|
51752
51939
|
keyboardShortcutsDescription: "Customize terminal copy, paste, and command shortcuts",
|
|
51753
51940
|
manageShortcuts: "Manage",
|
|
51754
|
-
historyTracking: "History Tracking",
|
|
51755
|
-
historyTrackingDesc: "Track terminal commands",
|
|
51756
51941
|
commandPalette: "Command Palette",
|
|
51757
51942
|
commandPaletteDesc: "Enable keyboard shortcut",
|
|
51758
51943
|
reopenTabsOnLogin: "Reopen Tabs on Login",
|
|
@@ -51765,28 +51950,16 @@ var en_default = {
|
|
|
51765
51950
|
sidebarSettingsMoved: "Host sidebar display settings have moved to the Customize sidebar panel, opened from the Hosts toolbar.",
|
|
51766
51951
|
showHostTags: "Show Host Tags",
|
|
51767
51952
|
showHostTagsDesc: "Display tags in host list",
|
|
51768
|
-
hostTrayOnClick: "Click to Expand Host Actions",
|
|
51769
|
-
hostTrayOnClickDesc: "Always show connection buttons; click to expand management options instead of hover",
|
|
51770
|
-
compactHostView: "Compact Host View",
|
|
51771
|
-
compactHostViewDesc: "Collapse each host to a single line showing only its name and address",
|
|
51772
51953
|
statusColors: "Real Status Colors",
|
|
51773
51954
|
statusColorsDesc: "Use green/red for online/offline status instead of the accent color",
|
|
51774
51955
|
pinAppRail: "Pin App Rail",
|
|
51775
51956
|
pinAppRailDesc: "Keep the left sidebar app rail always expanded instead of expanding on hover",
|
|
51776
|
-
openFullscreenSettings: "Open settings full screen",
|
|
51777
|
-
exitFullscreenSettings: "Exit full-screen settings",
|
|
51778
51957
|
expandAppRailOnHover: "Expand App Rail on Hover",
|
|
51779
51958
|
expandAppRailOnHoverDesc: "Allow the left sidebar app rail to expand when the pointer moves over it",
|
|
51780
51959
|
showPinAppRailButton: "Show Pin App Rail Button",
|
|
51781
51960
|
showPinAppRailButtonDesc: "Show a button in the app rail to pin it open. Off by default.",
|
|
51782
51961
|
settingsNavigation: "Navigation",
|
|
51783
51962
|
navigationTabsDesc: "Choose which tabs appear in the app rail",
|
|
51784
|
-
showSnippetCommands: "Show Commands",
|
|
51785
|
-
showSnippetCommandsDesc: "Show each snippet's command under its name. Turn off for a compact list.",
|
|
51786
|
-
foldersCollapsed: "Folders Collapsed",
|
|
51787
|
-
foldersCollapsedDesc: "Collapse folders by default",
|
|
51788
|
-
confirmExecution: "Confirm Execution",
|
|
51789
|
-
confirmExecutionDesc: "Confirm before running snippets",
|
|
51790
51963
|
settingsUpdates: "Updates",
|
|
51791
51964
|
disableUpdateChecks: "Disable Update Checks",
|
|
51792
51965
|
disableUpdateChecksDesc: "Stop checking for updates",
|
|
@@ -51876,7 +52049,6 @@ var en_default = {
|
|
|
51876
52049
|
}
|
|
51877
52050
|
}
|
|
51878
52051
|
},
|
|
51879
|
-
terminalToolbar: {},
|
|
51880
52052
|
plugins: {
|
|
51881
52053
|
capabilities: {
|
|
51882
52054
|
"credentials:read": {
|
|
@@ -51988,8 +52160,8 @@ var en_default = {
|
|
|
51988
52160
|
consequence: "Server settings, not your hosts or credentials."
|
|
51989
52161
|
},
|
|
51990
52162
|
"plugins:read": {
|
|
51991
|
-
title: "See installed
|
|
51992
|
-
consequence: "It can see which
|
|
52163
|
+
title: "See installed plugins",
|
|
52164
|
+
consequence: "It can see which plugins are installed and running."
|
|
51993
52165
|
},
|
|
51994
52166
|
"ui:surface": {
|
|
51995
52167
|
title: "Add its own screens",
|
|
@@ -51998,9 +52170,9 @@ var en_default = {
|
|
|
51998
52170
|
},
|
|
51999
52171
|
runtime: {
|
|
52000
52172
|
needsPlugin: "{{name}} is not available",
|
|
52001
|
-
needsUnknownPlugin: "This
|
|
52173
|
+
needsUnknownPlugin: "This plugin is not available",
|
|
52002
52174
|
disabledHint: "It is turned off on this server.",
|
|
52003
|
-
missingHint: "The
|
|
52175
|
+
missingHint: "The plugin it came from has been removed.",
|
|
52004
52176
|
failed: "{{name}} could not start",
|
|
52005
52177
|
failedHint: "An admin can check the server logs for details.",
|
|
52006
52178
|
loading: "Loading {{name}}",
|
|
@@ -52180,6 +52352,8 @@ var en_default = {
|
|
|
52180
52352
|
noneInstalled: "No plugins installed yet. Browse to add some.",
|
|
52181
52353
|
nothingHere: "Nothing here.",
|
|
52182
52354
|
nothingHereHint: "Try another category or search.",
|
|
52355
|
+
communitySoon: "Community plugins are coming in a later update. Plugin authors can already submit theirs to the community registry.",
|
|
52356
|
+
communitySubmit: "How to submit",
|
|
52183
52357
|
upToDate: "Everything is up to date.",
|
|
52184
52358
|
lastChecked: "Last checked {{time}}",
|
|
52185
52359
|
updatesReady_one: "{{count}} update ready.",
|
|
@@ -52229,7 +52403,11 @@ var en_default = {
|
|
|
52229
52403
|
waitingForStable: "Back on stable. Stays on {{version}} until a stable release is newer.",
|
|
52230
52404
|
versionLabel: "{{version}} (beta)",
|
|
52231
52405
|
sendFeedback: "Send beta feedback"
|
|
52232
|
-
}
|
|
52406
|
+
},
|
|
52407
|
+
documentation: "Documentation",
|
|
52408
|
+
envVars: "Environment variables",
|
|
52409
|
+
envRequired: "Required",
|
|
52410
|
+
envDefault: "Default: {{value}}"
|
|
52233
52411
|
}
|
|
52234
52412
|
},
|
|
52235
52413
|
settings: {
|
|
@@ -52368,7 +52546,7 @@ var en_default = {
|
|
|
52368
52546
|
sshCredentials: "Credentials",
|
|
52369
52547
|
sshFolders: "Folders",
|
|
52370
52548
|
userPreferences: "Preferences",
|
|
52371
|
-
pluginUserSettings: "
|
|
52549
|
+
pluginUserSettings: "Plugin settings",
|
|
52372
52550
|
sharedHosts: "Hosts shared with you",
|
|
52373
52551
|
sharedCredentials: "Credentials shared with you",
|
|
52374
52552
|
vaultProfiles: "Vault profiles",
|
|
@@ -52467,7 +52645,7 @@ var en_default = {
|
|
|
52467
52645
|
confirmNoChanges: "No existing host changes. New hosts will start with these defaults.",
|
|
52468
52646
|
menuMyDefaults: "My host defaults",
|
|
52469
52647
|
folderDefaultsAction: "Folder defaults",
|
|
52470
|
-
adminSectionDescription: "Set the defaults every host on this server follows, for every setting a host has, including each
|
|
52648
|
+
adminSectionDescription: "Set the defaults every host on this server follows, for every setting a host has, including each plugin's. Users and folders can set their own on top, and any host can still use its own value.",
|
|
52471
52649
|
editServerDefaults: "Edit server defaults",
|
|
52472
52650
|
resetMenu: "Reset",
|
|
52473
52651
|
resetAll: "Everything to defaults",
|
|
@@ -52497,7 +52675,7 @@ var en_default = {
|
|
|
52497
52675
|
needsAttention_one: "One thing needs attention.",
|
|
52498
52676
|
needsAttention_other: "{{count}} things need attention.",
|
|
52499
52677
|
bandHost: "Host",
|
|
52500
|
-
bandFeatures: "Protocols and
|
|
52678
|
+
bandFeatures: "Protocols and plugins",
|
|
52501
52679
|
bandCredential: "Credential",
|
|
52502
52680
|
sshConnection: "SSH connection",
|
|
52503
52681
|
errorAddressRequired: "An address is required.",
|
|
@@ -52514,6 +52692,7 @@ var en_default = {
|
|
|
52514
52692
|
collapse: "Collapse",
|
|
52515
52693
|
expand: "Expand",
|
|
52516
52694
|
cannotBeUndone: "This cannot be undone.",
|
|
52695
|
+
hostNotFound: "Couldn't find that host. Try refreshing the list.",
|
|
52517
52696
|
hostCount_one: "{{count}} host",
|
|
52518
52697
|
hostCount_other: "{{count}} hosts",
|
|
52519
52698
|
credentialCount_one: "{{count}} credential",
|
|
@@ -52676,23 +52855,23 @@ import { useMemo as useMemo14, useSyncExternalStore as useSyncExternalStore3 } f
|
|
|
52676
52855
|
|
|
52677
52856
|
// src/ui/contexts/UiPreferencesContext.tsx
|
|
52678
52857
|
import {
|
|
52679
|
-
createContext as
|
|
52858
|
+
createContext as createContext8,
|
|
52680
52859
|
useCallback as useCallback19,
|
|
52681
|
-
useContext as
|
|
52860
|
+
useContext as useContext7,
|
|
52682
52861
|
useEffect as useEffect28,
|
|
52683
52862
|
useMemo as useMemo13,
|
|
52684
52863
|
useRef as useRef30,
|
|
52685
52864
|
useState as useState26
|
|
52686
52865
|
} from "react";
|
|
52687
|
-
import { jsx as
|
|
52688
|
-
var UiPreferencesContext =
|
|
52866
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
52867
|
+
var UiPreferencesContext = createContext8(
|
|
52689
52868
|
null
|
|
52690
52869
|
);
|
|
52691
52870
|
function useUiPreferencesContext() {
|
|
52692
|
-
return
|
|
52871
|
+
return useContext7(UiPreferencesContext);
|
|
52693
52872
|
}
|
|
52694
52873
|
function useAreaPreferences(area) {
|
|
52695
|
-
const ctx =
|
|
52874
|
+
const ctx = useContext7(UiPreferencesContext);
|
|
52696
52875
|
if (!ctx) return PRESETS.balanced[area];
|
|
52697
52876
|
return ctx.resolve(area);
|
|
52698
52877
|
}
|
|
@@ -52713,8 +52892,8 @@ registeredRailItems.subscribe(() => {
|
|
|
52713
52892
|
|
|
52714
52893
|
// src/ui/components/tab-strip.tsx
|
|
52715
52894
|
import { useEffect as useEffect29, useRef as useRef31, useState as useState27 } from "react";
|
|
52716
|
-
import { useTranslation as
|
|
52717
|
-
import { jsx as
|
|
52895
|
+
import { useTranslation as useTranslation5 } from "react-i18next";
|
|
52896
|
+
import { jsx as jsx34, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
52718
52897
|
function TabStrip({
|
|
52719
52898
|
tabs,
|
|
52720
52899
|
activeTab,
|
|
@@ -52725,7 +52904,7 @@ function TabStrip({
|
|
|
52725
52904
|
className
|
|
52726
52905
|
}) {
|
|
52727
52906
|
const ref = useRef31(null);
|
|
52728
|
-
const { t } =
|
|
52907
|
+
const { t } = useTranslation5();
|
|
52729
52908
|
const [scroll, setScroll] = useState27({ left: false, right: false });
|
|
52730
52909
|
useEffect29(() => {
|
|
52731
52910
|
const el = ref.current;
|
|
@@ -52757,7 +52936,7 @@ function TabStrip({
|
|
|
52757
52936
|
}, []);
|
|
52758
52937
|
const renderTab = (tab) => {
|
|
52759
52938
|
const active = isActive ? isActive(tab.id) : activeTab === tab.id;
|
|
52760
|
-
return /* @__PURE__ */
|
|
52939
|
+
return /* @__PURE__ */ jsxs10(
|
|
52761
52940
|
"button",
|
|
52762
52941
|
{
|
|
52763
52942
|
type: "button",
|
|
@@ -52766,14 +52945,14 @@ function TabStrip({
|
|
|
52766
52945
|
children: [
|
|
52767
52946
|
tab.icon,
|
|
52768
52947
|
tab.label,
|
|
52769
|
-
tab.count !== void 0 && /* @__PURE__ */
|
|
52948
|
+
tab.count !== void 0 && /* @__PURE__ */ jsx34("span", { className: "text-[10px] tabular-nums opacity-60", children: tab.count })
|
|
52770
52949
|
]
|
|
52771
52950
|
},
|
|
52772
52951
|
tab.id
|
|
52773
52952
|
);
|
|
52774
52953
|
};
|
|
52775
52954
|
const overflow = scroll.left || scroll.right;
|
|
52776
|
-
return /* @__PURE__ */
|
|
52955
|
+
return /* @__PURE__ */ jsxs10(
|
|
52777
52956
|
"div",
|
|
52778
52957
|
{
|
|
52779
52958
|
className: cn(
|
|
@@ -52782,7 +52961,7 @@ function TabStrip({
|
|
|
52782
52961
|
className
|
|
52783
52962
|
),
|
|
52784
52963
|
children: [
|
|
52785
|
-
overflow && /* @__PURE__ */
|
|
52964
|
+
overflow && /* @__PURE__ */ jsx34(
|
|
52786
52965
|
"button",
|
|
52787
52966
|
{
|
|
52788
52967
|
type: "button",
|
|
@@ -52794,11 +52973,11 @@ function TabStrip({
|
|
|
52794
52973
|
left: -ref.current.clientWidth * 0.75,
|
|
52795
52974
|
behavior: "smooth"
|
|
52796
52975
|
}),
|
|
52797
|
-
children: /* @__PURE__ */
|
|
52976
|
+
children: /* @__PURE__ */ jsx34(ChevronLeft, { className: "size-4" })
|
|
52798
52977
|
}
|
|
52799
52978
|
),
|
|
52800
|
-
/* @__PURE__ */
|
|
52801
|
-
overflow && /* @__PURE__ */
|
|
52979
|
+
/* @__PURE__ */ jsx34("div", { ref, className: "min-w-0 flex-1 overflow-x-auto scrollbar-none", children: /* @__PURE__ */ jsx34("div", { className: "flex min-w-max", children: tabs.map(renderTab) }) }),
|
|
52980
|
+
overflow && /* @__PURE__ */ jsx34(
|
|
52802
52981
|
"button",
|
|
52803
52982
|
{
|
|
52804
52983
|
type: "button",
|
|
@@ -52810,17 +52989,17 @@ function TabStrip({
|
|
|
52810
52989
|
left: ref.current.clientWidth * 0.75,
|
|
52811
52990
|
behavior: "smooth"
|
|
52812
52991
|
}),
|
|
52813
|
-
children: /* @__PURE__ */
|
|
52992
|
+
children: /* @__PURE__ */ jsx34(ChevronRight, { className: "size-4" })
|
|
52814
52993
|
}
|
|
52815
52994
|
),
|
|
52816
|
-
trailing && /* @__PURE__ */
|
|
52995
|
+
trailing && /* @__PURE__ */ jsx34("div", { className: "flex shrink-0 items-center gap-1 px-1", children: trailing })
|
|
52817
52996
|
]
|
|
52818
52997
|
}
|
|
52819
52998
|
);
|
|
52820
52999
|
}
|
|
52821
53000
|
|
|
52822
53001
|
// src/ui/sidebar/HostManagerTabs.tsx
|
|
52823
|
-
import { jsx as
|
|
53002
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
52824
53003
|
var sections = createRegistry(byOrderThenId);
|
|
52825
53004
|
var registerHostEditorSection = sections.register;
|
|
52826
53005
|
var unregisterHostEditorSection = sections.unregister;
|
|
@@ -53243,8 +53422,8 @@ function sectionPosition(section, order2 = 0) {
|
|
|
53243
53422
|
}
|
|
53244
53423
|
|
|
53245
53424
|
// src/ui/components/theme-provider.tsx
|
|
53246
|
-
import { createContext as
|
|
53247
|
-
import { jsx as
|
|
53425
|
+
import { createContext as createContext9, useContext as useContext8, useEffect as useEffect30, useState as useState28 } from "react";
|
|
53426
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
53248
53427
|
var ALL_THEME_CLASSES = [
|
|
53249
53428
|
"light",
|
|
53250
53429
|
"dark",
|
|
@@ -53261,7 +53440,7 @@ var initialState = {
|
|
|
53261
53440
|
setTheme: () => null,
|
|
53262
53441
|
setThemePreview: () => null
|
|
53263
53442
|
};
|
|
53264
|
-
var ThemeProviderContext =
|
|
53443
|
+
var ThemeProviderContext = createContext9(initialState);
|
|
53265
53444
|
function ThemeProvider({
|
|
53266
53445
|
children,
|
|
53267
53446
|
defaultTheme = "dark",
|
|
@@ -53293,10 +53472,10 @@ function ThemeProvider({
|
|
|
53293
53472
|
setPreviewTheme(preview);
|
|
53294
53473
|
}
|
|
53295
53474
|
};
|
|
53296
|
-
return /* @__PURE__ */
|
|
53475
|
+
return /* @__PURE__ */ jsx36(ThemeProviderContext.Provider, { ...props, value, children });
|
|
53297
53476
|
}
|
|
53298
53477
|
var useTheme = () => {
|
|
53299
|
-
const context =
|
|
53478
|
+
const context = useContext8(ThemeProviderContext);
|
|
53300
53479
|
if (context === void 0)
|
|
53301
53480
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
53302
53481
|
return context;
|
|
@@ -53504,162 +53683,13 @@ async function getPlugins() {
|
|
|
53504
53683
|
}
|
|
53505
53684
|
var PLUGINS_CHANGED_EVENT = "termix:plugins-changed";
|
|
53506
53685
|
|
|
53507
|
-
// src/ui/plugin-host/scope.tsx
|
|
53508
|
-
import {
|
|
53509
|
-
Component as Component2,
|
|
53510
|
-
createContext as createContext9,
|
|
53511
|
-
Suspense,
|
|
53512
|
-
useContext as useContext8
|
|
53513
|
-
} from "react";
|
|
53514
|
-
|
|
53515
|
-
// src/ui/plugin-host/host-scope.ts
|
|
53516
|
-
function isHostLike(value) {
|
|
53517
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
53518
|
-
if (!("id" in value)) return false;
|
|
53519
|
-
return "pluginSettings" in value || "ip" in value && "port" in value;
|
|
53520
|
-
}
|
|
53521
|
-
var cache = /* @__PURE__ */ new WeakMap();
|
|
53522
|
-
function scopeHost(value, pluginId) {
|
|
53523
|
-
if (!isHostLike(value)) return value;
|
|
53524
|
-
const full = shellHost(value.id)?.pluginSettings ?? value.pluginSettings;
|
|
53525
|
-
let perPlugin = cache.get(value);
|
|
53526
|
-
const hit = perPlugin?.get(pluginId);
|
|
53527
|
-
if (hit && hit.source === full) return hit.scoped;
|
|
53528
|
-
const own = full?.[pluginId];
|
|
53529
|
-
const scoped = { ...value, pluginSettings: own ? { [pluginId]: own } : {} };
|
|
53530
|
-
if (!perPlugin) {
|
|
53531
|
-
perPlugin = /* @__PURE__ */ new Map();
|
|
53532
|
-
cache.set(value, perPlugin);
|
|
53533
|
-
}
|
|
53534
|
-
perPlugin.set(pluginId, { source: full, scoped });
|
|
53535
|
-
return scoped;
|
|
53536
|
-
}
|
|
53537
|
-
function scopeHostArgs(args, pluginId) {
|
|
53538
|
-
return args.map(
|
|
53539
|
-
(arg) => isHostLike(arg) ? scopeHost(arg, pluginId) : scopeHostFields(arg, pluginId)
|
|
53540
|
-
);
|
|
53541
|
-
}
|
|
53542
|
-
var HOST_FIELDS = ["host", "sshHost", "hostConfig"];
|
|
53543
|
-
function scopeHostFields(value, pluginId) {
|
|
53544
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
53545
|
-
const record = value;
|
|
53546
|
-
let next = null;
|
|
53547
|
-
for (const field of HOST_FIELDS) {
|
|
53548
|
-
if (!(field in record)) continue;
|
|
53549
|
-
const scoped = scopeHost(record[field], pluginId);
|
|
53550
|
-
if (scoped === record[field]) continue;
|
|
53551
|
-
next ??= { ...record };
|
|
53552
|
-
next[field] = scoped;
|
|
53553
|
-
}
|
|
53554
|
-
return next ?? value;
|
|
53555
|
-
}
|
|
53556
|
-
function scopeHostCallback(fn, pluginId) {
|
|
53557
|
-
if (!fn) return fn;
|
|
53558
|
-
return ((...args) => fn(...scopeHostArgs(args, pluginId)));
|
|
53559
|
-
}
|
|
53560
|
-
|
|
53561
|
-
// src/ui/plugin-host/scope.tsx
|
|
53562
|
-
import { useTranslation as useTranslation4 } from "react-i18next";
|
|
53563
|
-
import { jsx as jsx35, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
53564
|
-
var PluginScopeContext = createContext9(null);
|
|
53565
|
-
function usePluginScope() {
|
|
53566
|
-
return useContext8(PluginScopeContext);
|
|
53567
|
-
}
|
|
53568
|
-
function CrashNotice({
|
|
53569
|
-
pluginId,
|
|
53570
|
-
onRetry
|
|
53571
|
-
}) {
|
|
53572
|
-
const { t } = useTranslation4();
|
|
53573
|
-
const name = getPluginRecord(pluginId)?.summary.name ?? pluginId;
|
|
53574
|
-
return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center justify-center gap-2 p-4 text-center text-sm text-muted-foreground", children: [
|
|
53575
|
-
/* @__PURE__ */ jsx35("span", { children: t("plugins.runtime.crashed", { name }) }),
|
|
53576
|
-
/* @__PURE__ */ jsx35(
|
|
53577
|
-
"button",
|
|
53578
|
-
{
|
|
53579
|
-
type: "button",
|
|
53580
|
-
className: "text-xs underline underline-offset-2 hover:text-foreground",
|
|
53581
|
-
onClick: onRetry,
|
|
53582
|
-
children: t("plugins.runtime.retry")
|
|
53583
|
-
}
|
|
53584
|
-
)
|
|
53585
|
-
] });
|
|
53586
|
-
}
|
|
53587
|
-
var PluginErrorBoundary = class extends Component2 {
|
|
53588
|
-
state = { error: false };
|
|
53589
|
-
static getDerivedStateFromError() {
|
|
53590
|
-
return { error: true };
|
|
53591
|
-
}
|
|
53592
|
-
componentDidCatch(error, info) {
|
|
53593
|
-
console.error(
|
|
53594
|
-
`[plugins] ${this.props.pluginId} crashed while rendering`,
|
|
53595
|
-
error,
|
|
53596
|
-
info.componentStack
|
|
53597
|
-
);
|
|
53598
|
-
}
|
|
53599
|
-
render() {
|
|
53600
|
-
if (this.state.error) {
|
|
53601
|
-
return /* @__PURE__ */ jsx35(
|
|
53602
|
-
CrashNotice,
|
|
53603
|
-
{
|
|
53604
|
-
pluginId: this.props.pluginId,
|
|
53605
|
-
onRetry: () => this.setState({ error: false })
|
|
53606
|
-
}
|
|
53607
|
-
);
|
|
53608
|
-
}
|
|
53609
|
-
return this.props.children;
|
|
53610
|
-
}
|
|
53611
|
-
};
|
|
53612
|
-
function PluginScope({
|
|
53613
|
-
pluginId,
|
|
53614
|
-
children
|
|
53615
|
-
}) {
|
|
53616
|
-
return /* @__PURE__ */ jsx35(PluginScopeContext.Provider, { value: pluginId, children: /* @__PURE__ */ jsx35(PluginErrorBoundary, { pluginId, children: /* @__PURE__ */ jsx35(Suspense, { fallback: null, children }) }) });
|
|
53617
|
-
}
|
|
53618
|
-
function withPluginScope(pluginId, Inner) {
|
|
53619
|
-
function Scoped(props) {
|
|
53620
|
-
return /* @__PURE__ */ jsx35(PluginScope, { pluginId, children: /* @__PURE__ */ jsx35(Inner, { ...scopeHostFields(props, pluginId) }) });
|
|
53621
|
-
}
|
|
53622
|
-
Scoped.displayName = `Plugin(${pluginId}:${Inner.displayName ?? Inner.name ?? "Component"})`;
|
|
53623
|
-
return Scoped;
|
|
53624
|
-
}
|
|
53625
|
-
var IconBoundary = class extends Component2 {
|
|
53626
|
-
state = { error: false };
|
|
53627
|
-
static getDerivedStateFromError() {
|
|
53628
|
-
return { error: true };
|
|
53629
|
-
}
|
|
53630
|
-
componentDidCatch(error) {
|
|
53631
|
-
console.error(`[plugins] ${this.props.pluginId} icon failed`, error);
|
|
53632
|
-
}
|
|
53633
|
-
render() {
|
|
53634
|
-
return this.state.error ? null : this.props.children;
|
|
53635
|
-
}
|
|
53636
|
-
};
|
|
53637
|
-
function withIconBoundary(pluginId, Icon2) {
|
|
53638
|
-
if (!Icon2) return void 0;
|
|
53639
|
-
function SafeIcon(props) {
|
|
53640
|
-
return /* @__PURE__ */ jsx35(IconBoundary, { pluginId, children: /* @__PURE__ */ jsx35(Icon2, { ...props }) });
|
|
53641
|
-
}
|
|
53642
|
-
SafeIcon.displayName = `PluginIcon(${pluginId})`;
|
|
53643
|
-
return SafeIcon;
|
|
53644
|
-
}
|
|
53645
|
-
function guardCallback(pluginId, fn, fallback) {
|
|
53646
|
-
if (!fn) return void 0;
|
|
53647
|
-
return (...args) => {
|
|
53648
|
-
try {
|
|
53649
|
-
return fn(...args);
|
|
53650
|
-
} catch (error) {
|
|
53651
|
-
console.error(`[plugins] ${pluginId} callback failed`, error);
|
|
53652
|
-
return fallback;
|
|
53653
|
-
}
|
|
53654
|
-
};
|
|
53655
|
-
}
|
|
53656
|
-
|
|
53657
53686
|
// src/ui/hooks/useSshAuthProviders.ts
|
|
53658
53687
|
import { useEffect as useEffect32, useMemo as useMemo15, useState as useState30 } from "react";
|
|
53659
53688
|
|
|
53660
53689
|
// src/ui/api/auth-methods-api.ts
|
|
53661
53690
|
function remember(data) {
|
|
53662
53691
|
if (data?.token) localStorage.setItem("jwt", data.token);
|
|
53692
|
+
if (data?.trustToken) localStorage.setItem(TRUST_TOKEN_KEY, data.trustToken);
|
|
53663
53693
|
if (data?.success && !data.requires_totp) markUserAuthenticated();
|
|
53664
53694
|
return data;
|
|
53665
53695
|
}
|
|
@@ -53813,7 +53843,7 @@ function contextKey(context) {
|
|
|
53813
53843
|
try {
|
|
53814
53844
|
return JSON.stringify(context);
|
|
53815
53845
|
} catch {
|
|
53816
|
-
return
|
|
53846
|
+
return Object.entries(context).map(([key, value]) => `${key}:${value == null ? "-" : typeof value}`).join(",");
|
|
53817
53847
|
}
|
|
53818
53848
|
}
|
|
53819
53849
|
|
|
@@ -53828,7 +53858,7 @@ import {
|
|
|
53828
53858
|
useSyncExternalStore as useSyncExternalStore6,
|
|
53829
53859
|
useState as useState31
|
|
53830
53860
|
} from "react";
|
|
53831
|
-
import { jsx as
|
|
53861
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
53832
53862
|
var StatusStoreContext = createContext10(null);
|
|
53833
53863
|
var ServerStatusContext = createContext10(null);
|
|
53834
53864
|
var activeStore = null;
|
|
@@ -53950,6 +53980,9 @@ var pluginHostBridge = {
|
|
|
53950
53980
|
}
|
|
53951
53981
|
return pluginId;
|
|
53952
53982
|
},
|
|
53983
|
+
useDocsUrl(pluginId, page, anchor) {
|
|
53984
|
+
return usePluginDocsUrl(pluginId, page, anchor);
|
|
53985
|
+
},
|
|
53953
53986
|
useTranslation(pluginId) {
|
|
53954
53987
|
const { t, i18n: i18n2 } = useI18nTranslation(pluginId);
|
|
53955
53988
|
return {
|
|
@@ -54176,6 +54209,18 @@ function pluginKey(pluginId, key) {
|
|
|
54176
54209
|
|
|
54177
54210
|
// src/ui/plugin-host/app.ts
|
|
54178
54211
|
var ONBOARDING_ID = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
54212
|
+
function createDocsApi(manifest) {
|
|
54213
|
+
const url = pluginDocsUrl(manifest?.docs);
|
|
54214
|
+
const page = (name, anchor) => url ? pluginDocsPage(url, name, anchor) : null;
|
|
54215
|
+
return {
|
|
54216
|
+
url,
|
|
54217
|
+
page,
|
|
54218
|
+
open(name, anchor) {
|
|
54219
|
+
const target = page(name, anchor);
|
|
54220
|
+
if (target) window.open(target, "_blank", "noopener,noreferrer");
|
|
54221
|
+
}
|
|
54222
|
+
};
|
|
54223
|
+
}
|
|
54179
54224
|
function createPluginApp(pluginId, manifest, contributes, options2 = {}) {
|
|
54180
54225
|
const bag = [];
|
|
54181
54226
|
let disposed = false;
|
|
@@ -54580,6 +54625,7 @@ function createPluginApp(pluginId, manifest, contributes, options2 = {}) {
|
|
|
54580
54625
|
onReady: (listener) => track(tabsApi.onReady(listener))
|
|
54581
54626
|
},
|
|
54582
54627
|
confirm: (options3) => shell.confirm(options3),
|
|
54628
|
+
docs: createDocsApi(manifest),
|
|
54583
54629
|
desktop: {
|
|
54584
54630
|
available: isElectron(),
|
|
54585
54631
|
remoteServerUrl,
|
|
@@ -54622,8 +54668,8 @@ function createPluginApp(pluginId, manifest, contributes, options2 = {}) {
|
|
|
54622
54668
|
|
|
54623
54669
|
// src/ui/shell/ActionSlot.tsx
|
|
54624
54670
|
import React50 from "react";
|
|
54625
|
-
import { useTranslation as
|
|
54626
|
-
import { Fragment as Fragment14, jsx as
|
|
54671
|
+
import { useTranslation as useTranslation6 } from "react-i18next";
|
|
54672
|
+
import { Fragment as Fragment14, jsx as jsx38, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
54627
54673
|
function ActionSlot({
|
|
54628
54674
|
slotId,
|
|
54629
54675
|
context,
|
|
@@ -54633,17 +54679,17 @@ function ActionSlot({
|
|
|
54633
54679
|
hideLabels,
|
|
54634
54680
|
when
|
|
54635
54681
|
}) {
|
|
54636
|
-
const { t } =
|
|
54682
|
+
const { t } = useTranslation6();
|
|
54637
54683
|
const contributions2 = useActionSlot(slotId, when).filter(
|
|
54638
54684
|
(contribution) => contribution.kind !== "component"
|
|
54639
54685
|
);
|
|
54640
54686
|
if (!enabled || contributions2.length === 0) return null;
|
|
54641
|
-
return /* @__PURE__ */
|
|
54687
|
+
return /* @__PURE__ */ jsx38(Fragment14, { children: contributions2.map((contribution) => {
|
|
54642
54688
|
const invoke = () => {
|
|
54643
54689
|
void invokeAction(contribution.actionId, ...context?.() ?? []);
|
|
54644
54690
|
};
|
|
54645
54691
|
if (renderItem) {
|
|
54646
|
-
return /* @__PURE__ */
|
|
54692
|
+
return /* @__PURE__ */ jsx38(React50.Fragment, { children: renderItem(contribution, invoke) }, contribution.actionId);
|
|
54647
54693
|
}
|
|
54648
54694
|
const Icon2 = contribution.icon;
|
|
54649
54695
|
const label = t(contribution.titleKey);
|
|
@@ -54656,7 +54702,7 @@ function ActionSlot({
|
|
|
54656
54702
|
title: label,
|
|
54657
54703
|
onClick: invoke,
|
|
54658
54704
|
children: [
|
|
54659
|
-
Icon2 && /* @__PURE__ */
|
|
54705
|
+
Icon2 && /* @__PURE__ */ jsx38(Icon2, { className: "size-4 shrink-0" }),
|
|
54660
54706
|
!hideLabels && label
|
|
54661
54707
|
]
|
|
54662
54708
|
},
|
|
@@ -54673,37 +54719,37 @@ function ComponentSlot({
|
|
|
54673
54719
|
(contribution) => contribution.kind === "component" && contribution.component
|
|
54674
54720
|
);
|
|
54675
54721
|
if (contributions2.length === 0) return null;
|
|
54676
|
-
return /* @__PURE__ */
|
|
54722
|
+
return /* @__PURE__ */ jsx38(Fragment14, { children: contributions2.map((contribution) => {
|
|
54677
54723
|
const Contributed = contribution.component;
|
|
54678
|
-
return /* @__PURE__ */
|
|
54724
|
+
return /* @__PURE__ */ jsx38(Contributed, { ...props ?? {} }, contribution.actionId);
|
|
54679
54725
|
}) });
|
|
54680
54726
|
}
|
|
54681
54727
|
|
|
54682
54728
|
// src/ui/plugin-host/PluginViewPlaceholder.tsx
|
|
54683
|
-
import { useTranslation as
|
|
54729
|
+
import { useTranslation as useTranslation7 } from "react-i18next";
|
|
54684
54730
|
|
|
54685
54731
|
// src/ui/plugins/open-plugins.ts
|
|
54686
54732
|
var OPEN_PLUGINS_EVENT = "termix:open-plugins";
|
|
54687
54733
|
|
|
54688
54734
|
// src/ui/plugin-host/PluginViewPlaceholder.tsx
|
|
54689
|
-
import { jsx as
|
|
54735
|
+
import { jsx as jsx39, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
54690
54736
|
function PluginViewPlaceholder({
|
|
54691
54737
|
kind,
|
|
54692
54738
|
viewId,
|
|
54693
54739
|
compact = false
|
|
54694
54740
|
}) {
|
|
54695
|
-
const { t } =
|
|
54741
|
+
const { t } = useTranslation7();
|
|
54696
54742
|
usePluginStore();
|
|
54697
54743
|
const { has } = usePermissions();
|
|
54698
54744
|
const { status, owner } = unregisteredViewStatus(kind, viewId);
|
|
54699
54745
|
const name = owner?.summary.name ?? viewId;
|
|
54700
54746
|
if (status === "loading") {
|
|
54701
|
-
return /* @__PURE__ */
|
|
54747
|
+
return /* @__PURE__ */ jsx39(
|
|
54702
54748
|
"div",
|
|
54703
54749
|
{
|
|
54704
54750
|
className: "flex h-full w-full items-center justify-center",
|
|
54705
54751
|
"aria-label": t("plugins.runtime.loading", { name }),
|
|
54706
|
-
children: /* @__PURE__ */
|
|
54752
|
+
children: /* @__PURE__ */ jsx39("div", { className: "size-5 rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground/70 animate-spin" })
|
|
54707
54753
|
}
|
|
54708
54754
|
);
|
|
54709
54755
|
}
|
|
@@ -54716,10 +54762,10 @@ function PluginViewPlaceholder({
|
|
|
54716
54762
|
"data-status": status,
|
|
54717
54763
|
className: `flex h-full w-full flex-col items-center justify-center gap-2 text-center ${compact ? "p-3" : "p-6"}`,
|
|
54718
54764
|
children: [
|
|
54719
|
-
/* @__PURE__ */
|
|
54720
|
-
/* @__PURE__ */
|
|
54721
|
-
/* @__PURE__ */
|
|
54722
|
-
!compact && status !== "failed" && has("admin.plugins.manage") && /* @__PURE__ */
|
|
54765
|
+
/* @__PURE__ */ jsx39(CircleSlash, { className: "size-6 text-muted-foreground/40" }),
|
|
54766
|
+
/* @__PURE__ */ jsx39("span", { className: "text-sm font-semibold text-muted-foreground", children: title }),
|
|
54767
|
+
/* @__PURE__ */ jsx39("span", { className: "text-xs text-muted-foreground/70", children: hint }),
|
|
54768
|
+
!compact && status !== "failed" && has("admin.plugins.manage") && /* @__PURE__ */ jsx39(
|
|
54723
54769
|
Button,
|
|
54724
54770
|
{
|
|
54725
54771
|
variant: "outline",
|
|
@@ -54825,6 +54871,7 @@ export {
|
|
|
54825
54871
|
notifyShellReady,
|
|
54826
54872
|
resetShellBridge,
|
|
54827
54873
|
usePluginScope,
|
|
54874
|
+
DocsLink,
|
|
54828
54875
|
PANEL,
|
|
54829
54876
|
PanelShell,
|
|
54830
54877
|
BackButton,
|