@termix-ssh/plugin-sdk 1.0.21 → 1.0.23
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 +32 -0
- package/PLUGIN-GUIDE.md +130 -3
- package/cli/commands/build.mjs +55 -36
- package/cli/commands/validate.mjs +4 -0
- package/dist/backend.d.ts +139 -7
- package/dist/capabilities.js +3 -0
- package/dist/frontend.d.ts +7 -0
- package/dist/host/{PluginsTab-HQGSDSHS.js → PluginsTab-MNQU5OJ3.js} +22 -14
- package/dist/host/{chunk-JFQGI4OD.js → chunk-6WLECSNB.js} +71 -12
- package/dist/host/chunk-BP42N374.js +53 -0
- package/dist/host/{chunk-WWFRBU2E.js → chunk-C52NRTA6.js} +82 -51
- package/dist/host/{chunk-GTHINW3L.js → chunk-DN6YKMFJ.js} +34650 -34968
- package/dist/host/chunk-GBBKHJRQ.js +1526 -0
- package/dist/host/{chunk-FGX27MAA.js → chunk-GRH7GSKG.js} +1 -1
- package/dist/host/chunk-IMPLAAUM.js +345 -0
- package/dist/host/{chunk-A5CULDWV.js → chunk-X65V7ZRW.js} +121 -1574
- package/dist/host/core-classes.json +1 -1
- package/dist/host/frame-host.css +2 -0
- package/dist/host/frame-host.js +242 -0
- package/dist/host/{linked-server-UDSFY3N7.js → linked-server-YCAJ2NX3.js} +1 -1
- package/dist/host/{rbac-api-AAAPMF52.js → rbac-api-A64TXDL5.js} +5 -1
- package/dist/host/testing-host.js +9 -6
- package/dist/host/types/src/types/host-sidebar-preferences.d.ts +2 -0
- package/dist/host/types/src/types/index.d.ts +8 -0
- package/dist/host/types/src/ui/api/plugins-api.d.ts +2 -1
- package/dist/host/types/src/ui/api/rbac-api.d.ts +19 -1
- package/dist/host/types/src/ui/components/data-view.d.ts +1 -1
- package/dist/host/types/src/ui/lib/db-health-monitor.d.ts +5 -0
- package/dist/host/types/src/ui/main-axios.d.ts +1 -1
- package/dist/host/types/src/ui/plugin-host/loader.d.ts +6 -0
- package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +1 -1
- package/dist/host/types/src/ui/plugins/use-plugins-manager.d.ts +1 -1
- package/dist/host/types/src/ui/shell/tab-registry.d.ts +2 -0
- package/dist/host/ui.js +357 -370
- package/dist/host/{use-permissions-VAND5GEG.js → use-permissions-FLQAN6I7.js} +1 -1
- package/dist/host-commands.d.ts +7 -0
- package/dist/host-commands.js +35 -5
- package/dist/manifest.d.ts +33 -1
- package/dist/manifest.js +114 -1
- package/dist/operations.d.ts +222 -0
- package/dist/operations.js +650 -0
- package/dist/testing.d.ts +9 -1
- package/dist/testing.js +45 -0
- package/package.json +9 -1
- package/schema/manifest.schema.json +67 -0
|
@@ -29,12 +29,19 @@ import {
|
|
|
29
29
|
sortPlugins,
|
|
30
30
|
uploadEntry,
|
|
31
31
|
youtubeEmbedUrl
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-C52NRTA6.js";
|
|
33
|
+
import {
|
|
34
|
+
Button,
|
|
35
|
+
FakeSwitch,
|
|
36
|
+
Input,
|
|
37
|
+
PluginIcon,
|
|
38
|
+
SectionCard,
|
|
39
|
+
hasSettingsPage
|
|
40
|
+
} from "./chunk-IMPLAAUM.js";
|
|
33
41
|
import {
|
|
34
42
|
ArrowDownWideNarrow,
|
|
35
43
|
BookOpen,
|
|
36
44
|
Bug,
|
|
37
|
-
Button,
|
|
38
45
|
Check,
|
|
39
46
|
ChevronLeft,
|
|
40
47
|
ChevronRight,
|
|
@@ -44,13 +51,11 @@ import {
|
|
|
44
51
|
Download,
|
|
45
52
|
ExternalLink,
|
|
46
53
|
Facts,
|
|
47
|
-
FakeSwitch,
|
|
48
54
|
FlaskConical,
|
|
49
55
|
GRID_SIZES,
|
|
50
56
|
Globe,
|
|
51
57
|
GroupHeading,
|
|
52
58
|
InlineView,
|
|
53
|
-
Input,
|
|
54
59
|
Library,
|
|
55
60
|
Lightbulb,
|
|
56
61
|
ListFilter,
|
|
@@ -58,12 +63,10 @@ import {
|
|
|
58
63
|
PanePrompt,
|
|
59
64
|
PanelShell,
|
|
60
65
|
Pin,
|
|
61
|
-
PluginIcon,
|
|
62
66
|
Puzzle,
|
|
63
67
|
RefreshCw,
|
|
64
68
|
RotateCcw,
|
|
65
69
|
Search,
|
|
66
|
-
SectionCard,
|
|
67
70
|
Select,
|
|
68
71
|
SelectContent,
|
|
69
72
|
SelectItem,
|
|
@@ -88,7 +91,6 @@ import {
|
|
|
88
91
|
getPluginRegistry,
|
|
89
92
|
getPlugins,
|
|
90
93
|
getRegistries,
|
|
91
|
-
hasSettingsPage,
|
|
92
94
|
installPlugin,
|
|
93
95
|
installUploadedPlugin,
|
|
94
96
|
openPluginSettings,
|
|
@@ -107,8 +109,8 @@ import {
|
|
|
107
109
|
updatePlugin,
|
|
108
110
|
uploadPlugin,
|
|
109
111
|
useConfirm
|
|
110
|
-
} from "./chunk-
|
|
111
|
-
import "./chunk-
|
|
112
|
+
} from "./chunk-DN6YKMFJ.js";
|
|
113
|
+
import "./chunk-6WLECSNB.js";
|
|
112
114
|
import {
|
|
113
115
|
__toESM,
|
|
114
116
|
define_import_meta_env_default,
|
|
@@ -1560,9 +1562,12 @@ function usePluginsManager() {
|
|
|
1560
1562
|
[run, t, failToast]
|
|
1561
1563
|
);
|
|
1562
1564
|
const requestUpload = useCallback2(
|
|
1563
|
-
async (file) => {
|
|
1565
|
+
async (file, signatureFile) => {
|
|
1564
1566
|
try {
|
|
1565
|
-
const preview = await uploadPlugin(
|
|
1567
|
+
const preview = await uploadPlugin(
|
|
1568
|
+
file,
|
|
1569
|
+
signatureFile ? await signatureFile.text() : void 0
|
|
1570
|
+
);
|
|
1566
1571
|
setConsent({
|
|
1567
1572
|
plugin: uploadEntry(preview),
|
|
1568
1573
|
mode: "upload",
|
|
@@ -2576,12 +2581,15 @@ function UploadButton({ manager }) {
|
|
|
2576
2581
|
{
|
|
2577
2582
|
ref: input,
|
|
2578
2583
|
type: "file",
|
|
2579
|
-
accept: ".tmxplug",
|
|
2584
|
+
accept: ".tmxplug,.sig",
|
|
2585
|
+
multiple: true,
|
|
2580
2586
|
className: "hidden",
|
|
2581
2587
|
onChange: (e) => {
|
|
2582
|
-
const
|
|
2588
|
+
const files = [...e.target.files ?? []];
|
|
2583
2589
|
e.target.value = "";
|
|
2584
|
-
|
|
2590
|
+
const file = files.find((f) => f.name.endsWith(".tmxplug"));
|
|
2591
|
+
const signature = files.find((f) => f.name.endsWith(".sig"));
|
|
2592
|
+
if (file) void manager.requestUpload(file, signature);
|
|
2585
2593
|
}
|
|
2586
2594
|
}
|
|
2587
2595
|
),
|
|
@@ -4428,7 +4428,7 @@ var FrontendLogger = class {
|
|
|
4428
4428
|
this.serviceName = serviceName;
|
|
4429
4429
|
this.serviceIcon = serviceIcon;
|
|
4430
4430
|
this.serviceColor = serviceColor;
|
|
4431
|
-
this.isDevelopment =
|
|
4431
|
+
this.isDevelopment = false;
|
|
4432
4432
|
}
|
|
4433
4433
|
getTimeStamp() {
|
|
4434
4434
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -4691,6 +4691,8 @@ var DatabaseHealthMonitor = class _DatabaseHealthMonitor {
|
|
|
4691
4691
|
static instance;
|
|
4692
4692
|
listeners = /* @__PURE__ */ new Map();
|
|
4693
4693
|
degradedActive = false;
|
|
4694
|
+
probe = null;
|
|
4695
|
+
probing = null;
|
|
4694
4696
|
constructor() {
|
|
4695
4697
|
}
|
|
4696
4698
|
static getInstance() {
|
|
@@ -4729,10 +4731,28 @@ var DatabaseHealthMonitor = class _DatabaseHealthMonitor {
|
|
|
4729
4731
|
const errorCode = errorLike.response?.data?.code || errorLike.code;
|
|
4730
4732
|
const lowerMessage = errorMessage.toLowerCase();
|
|
4731
4733
|
const isDatabaseError = lowerMessage.includes("database") || lowerMessage.includes("sqlite") || lowerMessage.includes("drizzle") || errorCode === "DATABASE_ERROR" || errorCode === "DB_CONNECTION_FAILED";
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4734
|
+
if (errorCode === "ERR_CANCELED" || lowerMessage === "canceled") return;
|
|
4735
|
+
const isBackendUnreachable = errorCode === "ERR_NETWORK" || errorCode === "ECONNREFUSED" || errorCode === "ECONNRESET" || lowerMessage.includes("network error") && errorLike.response === void 0;
|
|
4736
|
+
const isTimeout = errorCode === "ECONNABORTED" || errorCode === "ETIMEDOUT" || lowerMessage.includes("request aborted") || lowerMessage.includes("timeout");
|
|
4737
|
+
if (isDatabaseError || isBackendUnreachable) {
|
|
4738
|
+
this.markDegraded(errorMessage, errorCode);
|
|
4739
|
+
} else if (isTimeout) {
|
|
4740
|
+
if (!this.probe) {
|
|
4741
|
+
this.markDegraded(errorMessage, errorCode);
|
|
4742
|
+
return;
|
|
4743
|
+
}
|
|
4744
|
+
this.probing ??= this.probe().catch(() => false).then((reachable) => {
|
|
4745
|
+
if (!reachable) this.markDegraded(errorMessage, errorCode);
|
|
4746
|
+
}).finally(() => {
|
|
4747
|
+
this.probing = null;
|
|
4748
|
+
});
|
|
4735
4749
|
}
|
|
4750
|
+
}
|
|
4751
|
+
/** Sets the quick check used after a request times out. */
|
|
4752
|
+
setReachabilityProbe(probe) {
|
|
4753
|
+
this.probe = probe;
|
|
4754
|
+
}
|
|
4755
|
+
markDegraded(errorMessage, errorCode) {
|
|
4736
4756
|
if (!this.degradedActive) {
|
|
4737
4757
|
this.degradedActive = true;
|
|
4738
4758
|
this.emit("database-connection-degraded", {
|
|
@@ -5205,6 +5225,7 @@ function defaultHostSidebarPreferences() {
|
|
|
5205
5225
|
statusColorScheme: "accent",
|
|
5206
5226
|
openOnDoubleClick: false,
|
|
5207
5227
|
showFolderPaths: true,
|
|
5228
|
+
stripedRows: true,
|
|
5208
5229
|
hostClickBehavior: "newTab",
|
|
5209
5230
|
closeOnOpen: false,
|
|
5210
5231
|
barActions: {},
|
|
@@ -5273,6 +5294,7 @@ function sanitizeHostSidebarPreferences(input) {
|
|
|
5273
5294
|
) ? displayObj.statusColorScheme : defaults2.display.statusColorScheme,
|
|
5274
5295
|
openOnDoubleClick: typeof displayObj.openOnDoubleClick === "boolean" ? displayObj.openOnDoubleClick : defaults2.display.openOnDoubleClick,
|
|
5275
5296
|
showFolderPaths: typeof displayObj.showFolderPaths === "boolean" ? displayObj.showFolderPaths : defaults2.display.showFolderPaths,
|
|
5297
|
+
stripedRows: typeof displayObj.stripedRows === "boolean" ? displayObj.stripedRows : defaults2.display.stripedRows,
|
|
5276
5298
|
hostClickBehavior: HOST_CLICK_BEHAVIORS.includes(
|
|
5277
5299
|
displayObj.hostClickBehavior
|
|
5278
5300
|
) ? displayObj.hostClickBehavior : defaults2.display.hostClickBehavior,
|
|
@@ -6318,7 +6340,7 @@ async function updateRole(roleId, roleData) {
|
|
|
6318
6340
|
try {
|
|
6319
6341
|
const response = await rbacApi.put(`/rbac/roles/${roleId}`, roleData);
|
|
6320
6342
|
if (roleData.permissions) {
|
|
6321
|
-
const { notifyPermissionsChanged } = await import("./use-permissions-
|
|
6343
|
+
const { notifyPermissionsChanged } = await import("./use-permissions-FLQAN6I7.js");
|
|
6322
6344
|
notifyPermissionsChanged();
|
|
6323
6345
|
}
|
|
6324
6346
|
return response.data;
|
|
@@ -6404,9 +6426,11 @@ async function getFolderAccess(folder) {
|
|
|
6404
6426
|
throw handleApiError(error, "get folder access");
|
|
6405
6427
|
}
|
|
6406
6428
|
}
|
|
6407
|
-
async function revokeFolderAccess(ruleId) {
|
|
6429
|
+
async function revokeFolderAccess(ruleId, options = {}) {
|
|
6408
6430
|
try {
|
|
6409
|
-
await rbacApi.delete(`/rbac/folder/access/${ruleId}
|
|
6431
|
+
await rbacApi.delete(`/rbac/folder/access/${ruleId}`, {
|
|
6432
|
+
params: options.fromHosts ? { fromHosts: "true" } : void 0
|
|
6433
|
+
});
|
|
6410
6434
|
} catch (error) {
|
|
6411
6435
|
throw handleApiError(error, "revoke folder access");
|
|
6412
6436
|
}
|
|
@@ -6479,6 +6503,29 @@ async function getHostAuthOverride(hostId, protocol, sharedCopySyncId) {
|
|
|
6479
6503
|
throw handleApiError(error, "fetch host authentication override");
|
|
6480
6504
|
}
|
|
6481
6505
|
}
|
|
6506
|
+
async function getFolderAuthOverride(folder, protocol, sharedCopySyncId) {
|
|
6507
|
+
try {
|
|
6508
|
+
const target = await getSharedCopyTarget(0, sharedCopySyncId);
|
|
6509
|
+
const response = await target.api.get(`/rbac/folder-auth/${protocol}`, {
|
|
6510
|
+
params: { folder }
|
|
6511
|
+
});
|
|
6512
|
+
return response.data;
|
|
6513
|
+
} catch (error) {
|
|
6514
|
+
throw handleApiError(error, "fetch folder authentication override");
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
async function setFolderAuthOverride(folder, protocol, credentialId, sharedCopySyncId) {
|
|
6518
|
+
try {
|
|
6519
|
+
const target = await getSharedCopyTarget(0, sharedCopySyncId);
|
|
6520
|
+
const response = await target.api.put(`/rbac/folder-auth/${protocol}`, {
|
|
6521
|
+
folder,
|
|
6522
|
+
credentialId
|
|
6523
|
+
});
|
|
6524
|
+
return response.data;
|
|
6525
|
+
} catch (error) {
|
|
6526
|
+
throw handleApiError(error, "update folder authentication override");
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6482
6529
|
async function setHostAuthOverride(hostId, protocol, credentialId, sharedCopySyncId) {
|
|
6483
6530
|
try {
|
|
6484
6531
|
const target = await getSharedCopyTarget(hostId, sharedCopySyncId);
|
|
@@ -6705,7 +6752,7 @@ function createApiInstance(baseURL, serviceName = "API") {
|
|
|
6705
6752
|
operation: "request_start"
|
|
6706
6753
|
};
|
|
6707
6754
|
const logger = getLoggerForService(serviceName);
|
|
6708
|
-
const isDevMode =
|
|
6755
|
+
const isDevMode = false;
|
|
6709
6756
|
if (isDevMode) {
|
|
6710
6757
|
logger.requestStart(method, fullUrl, context);
|
|
6711
6758
|
}
|
|
@@ -6778,7 +6825,7 @@ function createApiInstance(baseURL, serviceName = "API") {
|
|
|
6778
6825
|
operation: "request_success"
|
|
6779
6826
|
};
|
|
6780
6827
|
const logger = getLoggerForService(serviceName);
|
|
6781
|
-
if (
|
|
6828
|
+
if (false) {
|
|
6782
6829
|
logger.requestSuccess(
|
|
6783
6830
|
method,
|
|
6784
6831
|
fullUrl,
|
|
@@ -6816,7 +6863,7 @@ function createApiInstance(baseURL, serviceName = "API") {
|
|
|
6816
6863
|
};
|
|
6817
6864
|
const logger = getLoggerForService(serviceName);
|
|
6818
6865
|
const isSilentRetry = !!error.config?.__silentRetry;
|
|
6819
|
-
if (
|
|
6866
|
+
if (false) {
|
|
6820
6867
|
if (status === 401) {
|
|
6821
6868
|
logger.authError(method, fullUrl, context);
|
|
6822
6869
|
} else if (status === 0 || !status) {
|
|
@@ -6870,7 +6917,7 @@ function isDev() {
|
|
|
6870
6917
|
if (isElectron()) {
|
|
6871
6918
|
return false;
|
|
6872
6919
|
}
|
|
6873
|
-
return
|
|
6920
|
+
return false;
|
|
6874
6921
|
}
|
|
6875
6922
|
var apiHost = define_import_meta_env_default.VITE_API_HOST || (typeof window !== "undefined" ? window.location.hostname : "localhost");
|
|
6876
6923
|
function getBackendUrl(path) {
|
|
@@ -6900,7 +6947,7 @@ function createRemoteOriginApiInstance(path) {
|
|
|
6900
6947
|
});
|
|
6901
6948
|
instance.interceptors.request.use(
|
|
6902
6949
|
async (config) => {
|
|
6903
|
-
const { getLinkedSession: getLinkedSession2 } = await import("./linked-server-
|
|
6950
|
+
const { getLinkedSession: getLinkedSession2 } = await import("./linked-server-YCAJ2NX3.js");
|
|
6904
6951
|
const linked = await getLinkedSession2();
|
|
6905
6952
|
config.baseURL = linked ? `${linked.serverUrl}${path}` : "http://no-server-configured";
|
|
6906
6953
|
if (config.headers.set) {
|
|
@@ -6927,6 +6974,16 @@ function initializeApiInstances() {
|
|
|
6927
6974
|
hostApi = createApiInstance(getApiUrl("/host", 30001), "HOST");
|
|
6928
6975
|
sshHostApi = hostApi;
|
|
6929
6976
|
authApi = createApiInstance(getApiUrl("", 30001), "AUTH");
|
|
6977
|
+
const healthApi = authApi;
|
|
6978
|
+
dbHealthMonitor.setReachabilityProbe(
|
|
6979
|
+
() => healthApi.get("/health", {
|
|
6980
|
+
timeout: 5e3,
|
|
6981
|
+
__silentRetry: true
|
|
6982
|
+
}).then(
|
|
6983
|
+
() => true,
|
|
6984
|
+
() => false
|
|
6985
|
+
)
|
|
6986
|
+
);
|
|
6930
6987
|
rbacApi = createApiInstance(getApiUrl("", 30001), "RBAC");
|
|
6931
6988
|
}
|
|
6932
6989
|
var hostApi;
|
|
@@ -7455,6 +7512,8 @@ export {
|
|
|
7455
7512
|
getSharedHosts,
|
|
7456
7513
|
revokeHostAccess,
|
|
7457
7514
|
getHostAuthOverride,
|
|
7515
|
+
getFolderAuthOverride,
|
|
7516
|
+
setFolderAuthOverride,
|
|
7458
7517
|
setHostAuthOverride,
|
|
7459
7518
|
shareCredential,
|
|
7460
7519
|
getCredentialAccess,
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const __termixNoGlob = () => ({});
|
|
2
|
+
import {
|
|
3
|
+
useTheme
|
|
4
|
+
} from "./chunk-X65V7ZRW.js";
|
|
5
|
+
import {
|
|
6
|
+
init_define_import_meta_env
|
|
7
|
+
} from "./chunk-YGYBM7SQ.js";
|
|
8
|
+
|
|
9
|
+
// src/ui/components/sonner.tsx
|
|
10
|
+
init_define_import_meta_env();
|
|
11
|
+
import { Toaster as Sonner } from "sonner";
|
|
12
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
|
+
var Toaster = ({ ...props }) => {
|
|
14
|
+
const { theme = "system" } = useTheme();
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
Sonner,
|
|
17
|
+
{
|
|
18
|
+
theme,
|
|
19
|
+
className: "toaster group",
|
|
20
|
+
toastOptions: {
|
|
21
|
+
classNames: {
|
|
22
|
+
toast: "group toast group-[.toaster]:bg-card group-[.toaster]:text-card-foreground group-[.toaster]:border-border group-[.toaster]:rounded-none! group-[.toaster]:shadow-lg group-[.toaster]:font-mono",
|
|
23
|
+
description: "group-[.toast]:text-muted-foreground",
|
|
24
|
+
actionButton: "group-[.toast]:bg-accent-brand group-[.toast]:text-white group-[.toast]:font-semibold",
|
|
25
|
+
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
|
|
26
|
+
success: "group-[.toast]:!text-accent-brand group-[.toast]:!border-accent-brand/30",
|
|
27
|
+
info: "group-[.toast]:!text-accent-brand group-[.toast]:!border-accent-brand/30",
|
|
28
|
+
error: "group-[.toast]:!text-destructive group-[.toast]:!border-destructive/30"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
style: {
|
|
32
|
+
"--radius": "0px",
|
|
33
|
+
"--normal-bg": "var(--card)",
|
|
34
|
+
"--normal-border": "var(--border)",
|
|
35
|
+
"--normal-text": "var(--card-foreground)",
|
|
36
|
+
"--success-bg": "var(--card)",
|
|
37
|
+
"--success-border": "var(--border)",
|
|
38
|
+
"--success-text": "var(--color-accent-brand)",
|
|
39
|
+
"--info-bg": "var(--card)",
|
|
40
|
+
"--info-border": "var(--border)",
|
|
41
|
+
"--info-text": "var(--color-accent-brand)",
|
|
42
|
+
"--error-bg": "var(--card)",
|
|
43
|
+
"--error-border": "var(--border)",
|
|
44
|
+
"--error-text": "var(--destructive)"
|
|
45
|
+
},
|
|
46
|
+
...props
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
Toaster
|
|
53
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const __termixNoGlob = () => ({});
|
|
2
2
|
import {
|
|
3
|
-
Button
|
|
3
|
+
Button
|
|
4
|
+
} from "./chunk-IMPLAAUM.js";
|
|
5
|
+
import {
|
|
4
6
|
ChevronRight,
|
|
5
7
|
PANEL,
|
|
6
8
|
Plus,
|
|
@@ -8,10 +10,10 @@ import {
|
|
|
8
10
|
cn,
|
|
9
11
|
gridSizeStyle,
|
|
10
12
|
useAreaPreferences
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DN6YKMFJ.js";
|
|
12
14
|
import {
|
|
13
15
|
isElectron
|
|
14
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-6WLECSNB.js";
|
|
15
17
|
import {
|
|
16
18
|
__commonJS,
|
|
17
19
|
__toESM,
|
|
@@ -2181,6 +2183,13 @@ function EmptyState({
|
|
|
2181
2183
|
// src/ui/components/data-view.tsx
|
|
2182
2184
|
init_define_import_meta_env();
|
|
2183
2185
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2186
|
+
function listColumnTemplates(columns) {
|
|
2187
|
+
return {
|
|
2188
|
+
base: columns.filter((column) => column.hideBelow === void 0).map((column) => column.width).join(" ") || "none",
|
|
2189
|
+
md: columns.filter((column) => column.hideBelow !== "lg").map((column) => column.width).join(" ") || "none",
|
|
2190
|
+
lg: columns.map((column) => column.width).join(" ") || "none"
|
|
2191
|
+
};
|
|
2192
|
+
}
|
|
2184
2193
|
var COLS = {
|
|
2185
2194
|
1: "grid-cols-1",
|
|
2186
2195
|
2: "grid-cols-2",
|
|
@@ -2205,6 +2214,7 @@ var XL_COLS = {
|
|
|
2205
2214
|
3: "xl:grid-cols-3",
|
|
2206
2215
|
4: "xl:grid-cols-4"
|
|
2207
2216
|
};
|
|
2217
|
+
var LIST_GRID_CLASS = "grid grid-cols-[var(--data-view-cols)] @min-[48rem]:grid-cols-[var(--data-view-cols-md)] @min-[64rem]:grid-cols-[var(--data-view-cols-lg)] gap-x-2 px-3";
|
|
2208
2218
|
function gridClass(columns) {
|
|
2209
2219
|
return cn(
|
|
2210
2220
|
COLS[columns.base ?? 1],
|
|
@@ -2213,6 +2223,11 @@ function gridClass(columns) {
|
|
|
2213
2223
|
columns.xl && XL_COLS[columns.xl]
|
|
2214
2224
|
);
|
|
2215
2225
|
}
|
|
2226
|
+
function columnVisibility(hideBelow) {
|
|
2227
|
+
if (hideBelow === "md") return "hidden @min-[48rem]:block";
|
|
2228
|
+
if (hideBelow === "lg") return "hidden @min-[64rem]:block";
|
|
2229
|
+
return "";
|
|
2230
|
+
}
|
|
2216
2231
|
function DataView({
|
|
2217
2232
|
items,
|
|
2218
2233
|
view,
|
|
@@ -2246,60 +2261,72 @@ function DataView({
|
|
|
2246
2261
|
}
|
|
2247
2262
|
);
|
|
2248
2263
|
}
|
|
2249
|
-
const
|
|
2250
|
-
const rowHeight = density === "compact" ? "h-7" : "h-9";
|
|
2251
|
-
return /* @__PURE__ */ jsxs2(
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2264
|
+
const templates = listColumnTemplates(listColumns);
|
|
2265
|
+
const rowHeight = density === "compact" ? "min-h-7" : "min-h-9";
|
|
2266
|
+
return /* @__PURE__ */ jsxs2(
|
|
2267
|
+
"div",
|
|
2268
|
+
{
|
|
2269
|
+
className: cn("@container border border-border bg-card", className),
|
|
2270
|
+
style: {
|
|
2271
|
+
"--data-view-cols": templates.base,
|
|
2272
|
+
"--data-view-cols-md": templates.md,
|
|
2273
|
+
"--data-view-cols-lg": templates.lg
|
|
2274
|
+
},
|
|
2275
|
+
role: "table",
|
|
2276
|
+
children: [
|
|
2277
|
+
/* @__PURE__ */ jsx3(
|
|
2278
|
+
"div",
|
|
2259
2279
|
{
|
|
2260
2280
|
className: cn(
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
column.hideBelow === "md" && "hidden md:block",
|
|
2264
|
-
column.hideBelow === "lg" && "hidden lg:block"
|
|
2281
|
+
LIST_GRID_CLASS,
|
|
2282
|
+
"sticky top-0 z-10 items-center border-b border-border bg-card text-[10px] font-semibold uppercase tracking-widest text-muted-foreground"
|
|
2265
2283
|
),
|
|
2266
|
-
children: column
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
),
|
|
2284
|
-
style: { gridTemplateColumns: template },
|
|
2285
|
-
children: listColumns.map((column) => /* @__PURE__ */ jsx3(
|
|
2284
|
+
children: listColumns.map((column) => /* @__PURE__ */ jsx3(
|
|
2285
|
+
"span",
|
|
2286
|
+
{
|
|
2287
|
+
className: cn(
|
|
2288
|
+
"truncate py-2",
|
|
2289
|
+
column.align === "end" && "text-right",
|
|
2290
|
+
columnVisibility(column.hideBelow)
|
|
2291
|
+
),
|
|
2292
|
+
children: column.header
|
|
2293
|
+
},
|
|
2294
|
+
column.key
|
|
2295
|
+
))
|
|
2296
|
+
}
|
|
2297
|
+
),
|
|
2298
|
+
/* @__PURE__ */ jsx3("div", { children: items.map((item) => {
|
|
2299
|
+
const active = isRowActive?.(item) ?? false;
|
|
2300
|
+
return /* @__PURE__ */ jsx3(
|
|
2286
2301
|
"div",
|
|
2287
2302
|
{
|
|
2303
|
+
onClick: onRowClick ? () => onRowClick(item) : void 0,
|
|
2288
2304
|
className: cn(
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2305
|
+
LIST_GRID_CLASS,
|
|
2306
|
+
"items-center border-b border-border/50 text-xs transition-colors last:border-0",
|
|
2307
|
+
rowHeight,
|
|
2308
|
+
onRowClick && "cursor-pointer",
|
|
2309
|
+
active ? "bg-accent-brand/10" : "hover:bg-muted/40"
|
|
2293
2310
|
),
|
|
2294
|
-
children:
|
|
2311
|
+
children: listColumns.map((column) => /* @__PURE__ */ jsx3(
|
|
2312
|
+
"div",
|
|
2313
|
+
{
|
|
2314
|
+
className: cn(
|
|
2315
|
+
"min-w-0 truncate",
|
|
2316
|
+
column.align === "end" && "text-right",
|
|
2317
|
+
columnVisibility(column.hideBelow)
|
|
2318
|
+
),
|
|
2319
|
+
children: column.cell(item)
|
|
2320
|
+
},
|
|
2321
|
+
column.key
|
|
2322
|
+
))
|
|
2295
2323
|
},
|
|
2296
|
-
|
|
2297
|
-
)
|
|
2298
|
-
}
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
] });
|
|
2324
|
+
getKey(item)
|
|
2325
|
+
);
|
|
2326
|
+
}) })
|
|
2327
|
+
]
|
|
2328
|
+
}
|
|
2329
|
+
);
|
|
2303
2330
|
}
|
|
2304
2331
|
|
|
2305
2332
|
// src/ui/lib/issue-url.ts
|
|
@@ -2402,6 +2429,8 @@ var CAPABILITY_CATALOG = [
|
|
|
2402
2429
|
entry("ssh:transport", "high"),
|
|
2403
2430
|
entry("device:serial", "high"),
|
|
2404
2431
|
entry("notify:hub", "high"),
|
|
2432
|
+
entry("operations:invoke", "high"),
|
|
2433
|
+
entry("operations:approve", "high"),
|
|
2405
2434
|
entry("ui:layout", "high"),
|
|
2406
2435
|
entry("hosts:write", "medium"),
|
|
2407
2436
|
entry("hosts:export", "high"),
|
|
@@ -2417,6 +2446,7 @@ var CAPABILITY_CATALOG = [
|
|
|
2417
2446
|
entry("users:read", "medium"),
|
|
2418
2447
|
entry("events:core", "medium"),
|
|
2419
2448
|
entry("notify:send", "medium"),
|
|
2449
|
+
entry("operations:provide", "medium"),
|
|
2420
2450
|
entry("audit:read", "medium"),
|
|
2421
2451
|
entry("desktop:window", "medium"),
|
|
2422
2452
|
entry("desktop:local", "high"),
|
|
@@ -2513,8 +2543,9 @@ function mergePlugins(installed, registry) {
|
|
|
2513
2543
|
latestBeta: entry2?.latestBeta ?? null,
|
|
2514
2544
|
channel: summary.channel ?? entry2?.channel ?? "stable",
|
|
2515
2545
|
isBeta: isPrerelease(summary.version),
|
|
2516
|
-
// The server keeps its own copy up to date
|
|
2517
|
-
|
|
2546
|
+
// The server keeps its own copy up to date, and a plugin that is off
|
|
2547
|
+
// should not ask for attention.
|
|
2548
|
+
updateAvailable: summary.runsOnServer || !summary.enabled ? false : entry2?.updateAvailable ?? false,
|
|
2518
2549
|
addedCapabilities: entry2?.addedCapabilities ?? [],
|
|
2519
2550
|
versions: entry2?.versions ?? [],
|
|
2520
2551
|
capabilities: summary.capabilities ?? [],
|