@termix-ssh/plugin-sdk 1.0.12 → 1.0.13
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 +16 -0
- package/PLUGIN-GUIDE.md +91 -59
- package/dist/backend.d.ts +404 -0
- package/dist/capabilities.js +5 -0
- package/dist/db.js +1 -0
- package/dist/desktop.d.ts +0 -243
- package/dist/frontend.d.ts +23 -2
- package/dist/host/{PluginsTab-EV4MSGY6.js → PluginsTab-OXQQ7M4I.js} +511 -178
- package/dist/host/{chunk-X4QZKO5G.js → chunk-54KCK6IZ.js} +52 -5
- package/dist/host/{chunk-XKA3DBB2.js → chunk-CALNJCHN.js} +114 -54
- package/dist/host/{chunk-RUPLD6RF.js → chunk-CN5UBTBP.js} +2 -86
- package/dist/host/{chunk-AWR6FYDO.js → chunk-ERGN4YW6.js} +5552 -5550
- package/dist/host/{chunk-VEWOYAMZ.js → chunk-T2PZWXFJ.js} +1 -1
- package/dist/host/core-classes.json +1 -1
- package/dist/host/{linked-server-B4NEG4MA.js → linked-server-5VFO4XQB.js} +1 -1
- package/dist/host/{rbac-api-OUO3LUOC.js → rbac-api-5YMBJAO5.js} +1 -1
- package/dist/host/testing-host.js +4 -4
- package/dist/host/types/src/types/onboarding.d.ts +0 -2
- package/dist/host/types/src/ui/api/audit-log-api.d.ts +0 -10
- package/dist/host/types/src/ui/api/credentials-api.d.ts +0 -22
- package/dist/host/types/src/ui/api/plugins-api.d.ts +4 -0
- package/dist/host/types/src/ui/api/settings-api.d.ts +0 -6
- package/dist/host/types/src/ui/api/ssh-host-management-api.d.ts +0 -28
- package/dist/host/types/src/ui/main-axios.d.ts +2 -2
- package/dist/host/types/src/ui/onboarding/onboarding-registry.d.ts +3 -1
- package/dist/host/types/src/ui/plugin-host/sdk-ui.d.ts +5 -6
- package/dist/host/types/src/ui/plugins/plugin-model.d.ts +20 -0
- package/dist/host/types/src/ui/plugins/use-plugins-manager.d.ts +3 -0
- package/dist/host/types/src/ui/sidebar/host-contributions.d.ts +10 -0
- package/dist/host/ui.js +14 -205
- package/dist/host/{use-permissions-6VSHHUMB.js → use-permissions-ISEDRY3J.js} +1 -1
- package/dist/manifest.d.ts +10 -1
- package/dist/manifest.js +16 -1
- package/dist/ssh-keys.d.ts +29 -0
- package/dist/ssh-keys.js +85 -0
- package/dist/testing.d.ts +32 -15
- package/dist/testing.js +218 -1
- package/package.json +5 -1
- package/schema/manifest.schema.json +10 -0
- package/dist/host/types/src/ui/sidebar/host-export-payload.d.ts +0 -30
|
@@ -17,23 +17,27 @@ import {
|
|
|
17
17
|
formatCount,
|
|
18
18
|
groupChanges,
|
|
19
19
|
isSevere,
|
|
20
|
+
kindsOf,
|
|
20
21
|
matchesQuery,
|
|
21
22
|
mergePlugins,
|
|
22
23
|
mergeReleaseNotes,
|
|
23
24
|
orderByRisk,
|
|
25
|
+
pageOf,
|
|
24
26
|
reportIssueUrl,
|
|
25
27
|
requestFeatureUrl,
|
|
26
28
|
require_semver,
|
|
27
29
|
sortPlugins,
|
|
28
30
|
uploadEntry,
|
|
29
31
|
youtubeEmbedUrl
|
|
30
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-54KCK6IZ.js";
|
|
31
33
|
import {
|
|
32
34
|
ArrowDownWideNarrow,
|
|
33
35
|
BookOpen,
|
|
34
36
|
Bug,
|
|
35
37
|
Button,
|
|
36
38
|
Check,
|
|
39
|
+
ChevronLeft,
|
|
40
|
+
ChevronRight,
|
|
37
41
|
Columns3,
|
|
38
42
|
DEVELOPER_MODE_CHANGED_EVENT,
|
|
39
43
|
Database,
|
|
@@ -49,6 +53,7 @@ import {
|
|
|
49
53
|
Input,
|
|
50
54
|
Library,
|
|
51
55
|
Lightbulb,
|
|
56
|
+
ListFilter,
|
|
52
57
|
PANEL,
|
|
53
58
|
PanePrompt,
|
|
54
59
|
PanelShell,
|
|
@@ -72,6 +77,7 @@ import {
|
|
|
72
77
|
TriangleAlert,
|
|
73
78
|
Upload,
|
|
74
79
|
ViewToggle,
|
|
80
|
+
X,
|
|
75
81
|
addRegistry,
|
|
76
82
|
cn,
|
|
77
83
|
deletePluginData,
|
|
@@ -101,8 +107,8 @@ import {
|
|
|
101
107
|
updatePlugin,
|
|
102
108
|
uploadPlugin,
|
|
103
109
|
useConfirm
|
|
104
|
-
} from "./chunk-
|
|
105
|
-
import "./chunk-
|
|
110
|
+
} from "./chunk-ERGN4YW6.js";
|
|
111
|
+
import "./chunk-CN5UBTBP.js";
|
|
106
112
|
import {
|
|
107
113
|
__toESM,
|
|
108
114
|
define_import_meta_env_default,
|
|
@@ -111,7 +117,7 @@ import {
|
|
|
111
117
|
|
|
112
118
|
// src/ui/plugins/PluginsTab.tsx
|
|
113
119
|
init_define_import_meta_env();
|
|
114
|
-
import { useEffect as useEffect5,
|
|
120
|
+
import { useEffect as useEffect5, useRef as useRef2, useState as useState5 } from "react";
|
|
115
121
|
import { useTranslation as useTranslation7 } from "react-i18next";
|
|
116
122
|
|
|
117
123
|
// src/ui/plugins/plugin-bits.tsx
|
|
@@ -898,7 +904,16 @@ function PluginDetail({
|
|
|
898
904
|
]
|
|
899
905
|
}
|
|
900
906
|
)
|
|
901
|
-
] }) : /* @__PURE__ */
|
|
907
|
+
] }) : plugin.unsupported ? /* @__PURE__ */ jsx5(
|
|
908
|
+
"span",
|
|
909
|
+
{
|
|
910
|
+
className: "text-xs text-muted-foreground",
|
|
911
|
+
title: t("plugins.manager.unsupportedHint"),
|
|
912
|
+
children: plugin.needsTermix ? t("plugins.manager.needsTermix", {
|
|
913
|
+
range: plugin.needsTermix
|
|
914
|
+
}) : t("plugins.manager.unsupported")
|
|
915
|
+
}
|
|
916
|
+
) : /* @__PURE__ */ jsxs5(
|
|
902
917
|
Button,
|
|
903
918
|
{
|
|
904
919
|
variant: "outline",
|
|
@@ -1936,7 +1951,7 @@ function PluginsTabBody() {
|
|
|
1936
1951
|
onTabChange: (id) => setSection(id)
|
|
1937
1952
|
}
|
|
1938
1953
|
),
|
|
1939
|
-
children: /* @__PURE__ */ jsxs6("div", { className: "min-h-0 flex-1
|
|
1954
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "flex min-h-0 flex-1 flex-col", children: [
|
|
1940
1955
|
manager.managedByServer && /* @__PURE__ */ jsx6(Notice, { children: t("plugins.manager.managedByServer") }),
|
|
1941
1956
|
manager.registryError && /* @__PURE__ */ jsx6(Notice, { children: t("plugins.manager.registryUnreachable", {
|
|
1942
1957
|
error: manager.registryError
|
|
@@ -1963,14 +1978,14 @@ function PluginsTabBody() {
|
|
|
1963
1978
|
layout,
|
|
1964
1979
|
layoutControls
|
|
1965
1980
|
}
|
|
1966
|
-
) : section === "updates" ? /* @__PURE__ */ jsx6(
|
|
1981
|
+
) : /* @__PURE__ */ jsx6("div", { className: "min-h-0 flex-1 overflow-y-auto thin-scrollbar", children: section === "updates" ? /* @__PURE__ */ jsx6(
|
|
1967
1982
|
UpdatesSection,
|
|
1968
1983
|
{
|
|
1969
1984
|
plugins: updates,
|
|
1970
1985
|
manager,
|
|
1971
1986
|
onOpen: setDetailId
|
|
1972
1987
|
}
|
|
1973
|
-
) : /* @__PURE__ */ jsx6(RegistriesSection, { manager })
|
|
1988
|
+
) : /* @__PURE__ */ jsx6(RegistriesSection, { manager }) })
|
|
1974
1989
|
] })
|
|
1975
1990
|
}
|
|
1976
1991
|
),
|
|
@@ -2030,7 +2045,7 @@ function Toolbar({
|
|
|
2030
2045
|
children
|
|
2031
2046
|
}) {
|
|
2032
2047
|
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2033
|
-
/* @__PURE__ */ jsxs6("div", { className: "relative min-w-40 max-w-
|
|
2048
|
+
/* @__PURE__ */ jsxs6("div", { className: "relative min-w-40 max-w-md flex-1", children: [
|
|
2034
2049
|
/* @__PURE__ */ jsx6(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
2035
2050
|
/* @__PURE__ */ jsx6(
|
|
2036
2051
|
Input,
|
|
@@ -2148,6 +2163,274 @@ function DescriptionCell({ plugin }) {
|
|
|
2148
2163
|
function stop(e) {
|
|
2149
2164
|
e.stopPropagation();
|
|
2150
2165
|
}
|
|
2166
|
+
var NO_FACETS = { kind: null, category: null, registry: null };
|
|
2167
|
+
function applyFacets(rows, facets, skip) {
|
|
2168
|
+
return rows.filter(
|
|
2169
|
+
(p) => (skip === "kind" || !facets.kind || p.kinds.includes(facets.kind)) && (skip === "category" || !facets.category || p.category === facets.category) && (skip === "registry" || !facets.registry || p.registryId === facets.registry)
|
|
2170
|
+
);
|
|
2171
|
+
}
|
|
2172
|
+
function activeFacets(facets) {
|
|
2173
|
+
return [facets.kind, facets.category, facets.registry].filter(Boolean).length;
|
|
2174
|
+
}
|
|
2175
|
+
var PAGE_SIZES = ["24", "48", "96"];
|
|
2176
|
+
function usePage(signature) {
|
|
2177
|
+
const [state, setState] = useState5({ signature, page: 1 });
|
|
2178
|
+
const page = state.signature === signature ? state.page : 1;
|
|
2179
|
+
return [page, (next) => setState({ signature, page: next })];
|
|
2180
|
+
}
|
|
2181
|
+
function FacetGroup({
|
|
2182
|
+
title,
|
|
2183
|
+
allLabel,
|
|
2184
|
+
options,
|
|
2185
|
+
value,
|
|
2186
|
+
onChange
|
|
2187
|
+
}) {
|
|
2188
|
+
if (options.length === 0) return null;
|
|
2189
|
+
const row = (key, label, count) => {
|
|
2190
|
+
const active = value === key;
|
|
2191
|
+
return /* @__PURE__ */ jsxs6(
|
|
2192
|
+
"button",
|
|
2193
|
+
{
|
|
2194
|
+
type: "button",
|
|
2195
|
+
"aria-pressed": active,
|
|
2196
|
+
onClick: () => onChange(key),
|
|
2197
|
+
className: cn(
|
|
2198
|
+
"flex w-full items-center gap-2 border-l-2 px-2.5 py-1 text-left text-xs transition-colors",
|
|
2199
|
+
active ? "border-accent-brand bg-accent-brand/10 text-accent-brand" : "border-transparent text-muted-foreground hover:bg-muted/50 hover:text-foreground",
|
|
2200
|
+
count === 0 && !active && "opacity-50"
|
|
2201
|
+
),
|
|
2202
|
+
children: [
|
|
2203
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate", children: label }),
|
|
2204
|
+
count !== void 0 && /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[10px] tabular-nums opacity-70", children: count })
|
|
2205
|
+
]
|
|
2206
|
+
},
|
|
2207
|
+
key ?? "__all"
|
|
2208
|
+
);
|
|
2209
|
+
};
|
|
2210
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-0.5", children: [
|
|
2211
|
+
/* @__PURE__ */ jsx6("span", { className: "px-2.5 pb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children: title }),
|
|
2212
|
+
row(null, allLabel),
|
|
2213
|
+
options.map((o) => row(o.value, o.label, o.count))
|
|
2214
|
+
] });
|
|
2215
|
+
}
|
|
2216
|
+
function FilterRail({
|
|
2217
|
+
rows,
|
|
2218
|
+
facets,
|
|
2219
|
+
onFacets,
|
|
2220
|
+
registries,
|
|
2221
|
+
children
|
|
2222
|
+
}) {
|
|
2223
|
+
const { t } = useTranslation7();
|
|
2224
|
+
const byKind = applyFacets(rows, facets, "kind");
|
|
2225
|
+
const kinds = kindsOf(rows).map(({ kind }) => ({
|
|
2226
|
+
value: kind,
|
|
2227
|
+
label: t(`plugins.manager.kinds.${kind}`),
|
|
2228
|
+
count: byKind.filter((p) => p.kinds.includes(kind)).length
|
|
2229
|
+
}));
|
|
2230
|
+
const byCategory = applyFacets(rows, facets, "category");
|
|
2231
|
+
const categories = categoriesOf(rows).map((c) => ({
|
|
2232
|
+
value: c,
|
|
2233
|
+
label: c,
|
|
2234
|
+
count: byCategory.filter((p) => p.category === c).length
|
|
2235
|
+
}));
|
|
2236
|
+
const byRegistry = applyFacets(rows, facets, "registry");
|
|
2237
|
+
const registryOptions = registries && registries.length > 1 ? registries.map((r) => ({
|
|
2238
|
+
value: r.id,
|
|
2239
|
+
label: r.name,
|
|
2240
|
+
count: byRegistry.filter((p) => p.registryId === r.id).length
|
|
2241
|
+
})) : [];
|
|
2242
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-4 py-3", children: [
|
|
2243
|
+
/* @__PURE__ */ jsx6(
|
|
2244
|
+
FacetGroup,
|
|
2245
|
+
{
|
|
2246
|
+
title: t("plugins.manager.filters.type"),
|
|
2247
|
+
allLabel: t("plugins.manager.filters.allTypes"),
|
|
2248
|
+
options: kinds,
|
|
2249
|
+
value: facets.kind,
|
|
2250
|
+
onChange: (kind) => onFacets({ ...facets, kind })
|
|
2251
|
+
}
|
|
2252
|
+
),
|
|
2253
|
+
/* @__PURE__ */ jsx6(
|
|
2254
|
+
FacetGroup,
|
|
2255
|
+
{
|
|
2256
|
+
title: t("plugins.manager.filters.category"),
|
|
2257
|
+
allLabel: t("plugins.manager.filters.allCategories"),
|
|
2258
|
+
options: categories,
|
|
2259
|
+
value: facets.category,
|
|
2260
|
+
onChange: (category) => onFacets({ ...facets, category })
|
|
2261
|
+
}
|
|
2262
|
+
),
|
|
2263
|
+
/* @__PURE__ */ jsx6(
|
|
2264
|
+
FacetGroup,
|
|
2265
|
+
{
|
|
2266
|
+
title: t("plugins.manager.registries.filter"),
|
|
2267
|
+
allLabel: t("plugins.manager.registries.allRegistries"),
|
|
2268
|
+
options: registryOptions,
|
|
2269
|
+
value: facets.registry,
|
|
2270
|
+
onChange: (registry) => onFacets({ ...facets, registry })
|
|
2271
|
+
}
|
|
2272
|
+
),
|
|
2273
|
+
children && /* @__PURE__ */ jsx6("div", { className: "flex flex-col gap-2.5 border-t border-border px-2.5 pt-3", children })
|
|
2274
|
+
] });
|
|
2275
|
+
}
|
|
2276
|
+
function RailToggle({
|
|
2277
|
+
label,
|
|
2278
|
+
hint,
|
|
2279
|
+
checked,
|
|
2280
|
+
onChange
|
|
2281
|
+
}) {
|
|
2282
|
+
return /* @__PURE__ */ jsxs6("label", { className: "flex items-center justify-between gap-2", title: hint, children: [
|
|
2283
|
+
/* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: label }),
|
|
2284
|
+
/* @__PURE__ */ jsx6(FakeSwitch, { checked, onChange })
|
|
2285
|
+
] });
|
|
2286
|
+
}
|
|
2287
|
+
function ActiveFilters({
|
|
2288
|
+
facets,
|
|
2289
|
+
onFacets,
|
|
2290
|
+
registries,
|
|
2291
|
+
shown
|
|
2292
|
+
}) {
|
|
2293
|
+
const { t } = useTranslation7();
|
|
2294
|
+
const chips = [];
|
|
2295
|
+
if (facets.kind) {
|
|
2296
|
+
chips.push({
|
|
2297
|
+
key: "kind",
|
|
2298
|
+
label: t(`plugins.manager.kinds.${facets.kind}`)
|
|
2299
|
+
});
|
|
2300
|
+
}
|
|
2301
|
+
if (facets.category) chips.push({ key: "category", label: facets.category });
|
|
2302
|
+
if (facets.registry) {
|
|
2303
|
+
chips.push({
|
|
2304
|
+
key: "registry",
|
|
2305
|
+
label: registries?.find((r) => r.id === facets.registry)?.name ?? facets.registry
|
|
2306
|
+
});
|
|
2307
|
+
}
|
|
2308
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex min-h-6 flex-wrap items-center gap-1.5", children: [
|
|
2309
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[11px] text-muted-foreground", children: t("plugins.manager.filters.results", { count: shown }) }),
|
|
2310
|
+
chips.map((chip) => /* @__PURE__ */ jsxs6(
|
|
2311
|
+
"button",
|
|
2312
|
+
{
|
|
2313
|
+
type: "button",
|
|
2314
|
+
onClick: () => onFacets({ ...facets, [chip.key]: null }),
|
|
2315
|
+
className: "flex items-center gap-1 border border-accent-brand/40 bg-accent-brand/10 px-1.5 py-0.5 text-[11px] text-accent-brand hover:bg-accent-brand/20",
|
|
2316
|
+
"aria-label": t("plugins.manager.filters.remove", {
|
|
2317
|
+
name: chip.label
|
|
2318
|
+
}),
|
|
2319
|
+
children: [
|
|
2320
|
+
chip.label,
|
|
2321
|
+
/* @__PURE__ */ jsx6(X, { className: "size-3" })
|
|
2322
|
+
]
|
|
2323
|
+
},
|
|
2324
|
+
chip.key
|
|
2325
|
+
)),
|
|
2326
|
+
chips.length > 1 && /* @__PURE__ */ jsx6(
|
|
2327
|
+
"button",
|
|
2328
|
+
{
|
|
2329
|
+
type: "button",
|
|
2330
|
+
onClick: () => onFacets(NO_FACETS),
|
|
2331
|
+
className: "text-[11px] text-muted-foreground hover:text-foreground",
|
|
2332
|
+
children: t("plugins.manager.filters.clear")
|
|
2333
|
+
}
|
|
2334
|
+
)
|
|
2335
|
+
] });
|
|
2336
|
+
}
|
|
2337
|
+
function Pager({
|
|
2338
|
+
page,
|
|
2339
|
+
pages,
|
|
2340
|
+
total,
|
|
2341
|
+
size,
|
|
2342
|
+
onPage,
|
|
2343
|
+
onSize
|
|
2344
|
+
}) {
|
|
2345
|
+
const { t } = useTranslation7();
|
|
2346
|
+
const per = Number(size);
|
|
2347
|
+
if (total <= Number(PAGE_SIZES[0])) return null;
|
|
2348
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center gap-2 border-t border-border pt-2.5", children: [
|
|
2349
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[11px] tabular-nums text-muted-foreground", children: t("plugins.manager.pager.range", {
|
|
2350
|
+
from: (page - 1) * per + 1,
|
|
2351
|
+
to: Math.min(page * per, total),
|
|
2352
|
+
total
|
|
2353
|
+
}) }),
|
|
2354
|
+
/* @__PURE__ */ jsxs6("div", { className: "ml-auto flex items-center gap-1.5", children: [
|
|
2355
|
+
/* @__PURE__ */ jsxs6(Select, { value: size, onValueChange: (v) => onSize(v), children: [
|
|
2356
|
+
/* @__PURE__ */ jsx6(
|
|
2357
|
+
SelectTrigger,
|
|
2358
|
+
{
|
|
2359
|
+
size: "sm",
|
|
2360
|
+
className: "w-auto text-xs",
|
|
2361
|
+
"aria-label": t("plugins.manager.pager.perPageLabel"),
|
|
2362
|
+
children: /* @__PURE__ */ jsx6(SelectValue, {})
|
|
2363
|
+
}
|
|
2364
|
+
),
|
|
2365
|
+
/* @__PURE__ */ jsx6(SelectContent, { children: PAGE_SIZES.map((n) => /* @__PURE__ */ jsx6(SelectItem, { value: n, className: "text-xs", children: t("plugins.manager.pager.perPage", { count: Number(n) }) }, n)) })
|
|
2366
|
+
] }),
|
|
2367
|
+
/* @__PURE__ */ jsx6(
|
|
2368
|
+
Button,
|
|
2369
|
+
{
|
|
2370
|
+
variant: "outline",
|
|
2371
|
+
size: "icon-sm",
|
|
2372
|
+
disabled: page <= 1,
|
|
2373
|
+
onClick: () => onPage(page - 1),
|
|
2374
|
+
title: t("plugins.manager.pager.previous"),
|
|
2375
|
+
"aria-label": t("plugins.manager.pager.previous"),
|
|
2376
|
+
children: /* @__PURE__ */ jsx6(ChevronLeft, { className: "size-3.5" })
|
|
2377
|
+
}
|
|
2378
|
+
),
|
|
2379
|
+
/* @__PURE__ */ jsx6("span", { className: "px-1 text-[11px] tabular-nums text-muted-foreground", children: t("plugins.manager.pager.page", { page, pages }) }),
|
|
2380
|
+
/* @__PURE__ */ jsx6(
|
|
2381
|
+
Button,
|
|
2382
|
+
{
|
|
2383
|
+
variant: "outline",
|
|
2384
|
+
size: "icon-sm",
|
|
2385
|
+
disabled: page >= pages,
|
|
2386
|
+
onClick: () => onPage(page + 1),
|
|
2387
|
+
title: t("plugins.manager.pager.next"),
|
|
2388
|
+
"aria-label": t("plugins.manager.pager.next"),
|
|
2389
|
+
children: /* @__PURE__ */ jsx6(ChevronRight, { className: "size-3.5" })
|
|
2390
|
+
}
|
|
2391
|
+
)
|
|
2392
|
+
] })
|
|
2393
|
+
] });
|
|
2394
|
+
}
|
|
2395
|
+
function FilteredLayout({
|
|
2396
|
+
rail,
|
|
2397
|
+
activeCount,
|
|
2398
|
+
scrollRef,
|
|
2399
|
+
children
|
|
2400
|
+
}) {
|
|
2401
|
+
const { t } = useTranslation7();
|
|
2402
|
+
const [open, setOpen] = useState5(false);
|
|
2403
|
+
const button = /* @__PURE__ */ jsxs6(
|
|
2404
|
+
Button,
|
|
2405
|
+
{
|
|
2406
|
+
variant: "outline",
|
|
2407
|
+
className: cn(
|
|
2408
|
+
"gap-1.5 @3xl:hidden",
|
|
2409
|
+
activeCount > 0 && "border-accent-brand/40 text-accent-brand"
|
|
2410
|
+
),
|
|
2411
|
+
"aria-expanded": open,
|
|
2412
|
+
onClick: () => setOpen((v) => !v),
|
|
2413
|
+
children: [
|
|
2414
|
+
/* @__PURE__ */ jsx6(ListFilter, { className: "size-3.5" }),
|
|
2415
|
+
activeCount > 0 ? t("plugins.manager.filters.buttonCount", { count: activeCount }) : t("plugins.manager.filters.button")
|
|
2416
|
+
]
|
|
2417
|
+
}
|
|
2418
|
+
);
|
|
2419
|
+
return /* @__PURE__ */ jsxs6("div", { className: "@container flex min-h-0 flex-1", children: [
|
|
2420
|
+
/* @__PURE__ */ jsx6("aside", { className: "hidden w-52 shrink-0 overflow-y-auto border-r border-border thin-scrollbar @3xl:block", children: rail }),
|
|
2421
|
+
/* @__PURE__ */ jsxs6(
|
|
2422
|
+
"div",
|
|
2423
|
+
{
|
|
2424
|
+
ref: scrollRef,
|
|
2425
|
+
className: "min-h-0 flex-1 overflow-y-auto thin-scrollbar",
|
|
2426
|
+
children: [
|
|
2427
|
+
open && /* @__PURE__ */ jsx6("div", { className: "border-b border-border @3xl:hidden", children: rail }),
|
|
2428
|
+
children(button)
|
|
2429
|
+
]
|
|
2430
|
+
}
|
|
2431
|
+
)
|
|
2432
|
+
] });
|
|
2433
|
+
}
|
|
2151
2434
|
function InstalledSection({
|
|
2152
2435
|
plugins,
|
|
2153
2436
|
manager,
|
|
@@ -2159,10 +2442,9 @@ function InstalledSection({
|
|
|
2159
2442
|
}) {
|
|
2160
2443
|
const { t } = useTranslation7();
|
|
2161
2444
|
const [sort, setSort] = useState5("name");
|
|
2162
|
-
const
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
);
|
|
2445
|
+
const [facets, setFacets] = useState5(NO_FACETS);
|
|
2446
|
+
const searched = plugins.filter((p) => matchesQuery(p, query));
|
|
2447
|
+
const rows = sortPlugins(applyFacets(searched, facets), sort);
|
|
2166
2448
|
const running = rows.filter((p) => p.status === "running");
|
|
2167
2449
|
const onServer = rows.filter((p) => p.status === "server");
|
|
2168
2450
|
const stopped = rows.filter(
|
|
@@ -2224,66 +2506,84 @@ function InstalledSection({
|
|
|
2224
2506
|
onOpen
|
|
2225
2507
|
}
|
|
2226
2508
|
);
|
|
2227
|
-
return /* @__PURE__ */
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2509
|
+
return /* @__PURE__ */ jsx6(
|
|
2510
|
+
FilteredLayout,
|
|
2511
|
+
{
|
|
2512
|
+
activeCount: activeFacets(facets),
|
|
2513
|
+
rail: /* @__PURE__ */ jsx6(FilterRail, { rows: searched, facets, onFacets: setFacets }),
|
|
2514
|
+
children: (filtersButton) => /* @__PURE__ */ jsxs6("div", { className: `flex flex-col ${PANEL.gap} ${PANEL.body}`, children: [
|
|
2515
|
+
/* @__PURE__ */ jsxs6(
|
|
2516
|
+
Toolbar,
|
|
2517
|
+
{
|
|
2518
|
+
query,
|
|
2519
|
+
onQuery,
|
|
2520
|
+
placeholder: t("plugins.manager.searchInstalled"),
|
|
2521
|
+
children: [
|
|
2522
|
+
filtersButton,
|
|
2523
|
+
/* @__PURE__ */ jsxs6("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
2524
|
+
/* @__PURE__ */ jsx6(SortSelect, { value: sort, onChange: setSort }),
|
|
2525
|
+
layoutControls,
|
|
2526
|
+
manager.developerMode && !manager.signedOnly && /* @__PURE__ */ jsx6(UploadButton, { manager }),
|
|
2527
|
+
/* @__PURE__ */ jsxs6(
|
|
2528
|
+
Button,
|
|
2529
|
+
{
|
|
2530
|
+
variant: "outline",
|
|
2531
|
+
className: "gap-1.5",
|
|
2532
|
+
disabled: pending.length === 0 || manager.busy.size > 0 || manager.managedByServer,
|
|
2533
|
+
onClick: () => void manager.updateAll(),
|
|
2534
|
+
children: [
|
|
2535
|
+
/* @__PURE__ */ jsx6(Download, { className: "size-3.5" }),
|
|
2536
|
+
t("plugins.manager.updateAll")
|
|
2537
|
+
]
|
|
2538
|
+
}
|
|
2539
|
+
)
|
|
2540
|
+
] })
|
|
2541
|
+
]
|
|
2542
|
+
}
|
|
2543
|
+
),
|
|
2544
|
+
activeFacets(facets) > 0 && /* @__PURE__ */ jsx6(
|
|
2545
|
+
ActiveFilters,
|
|
2546
|
+
{
|
|
2547
|
+
facets,
|
|
2548
|
+
onFacets: setFacets,
|
|
2549
|
+
shown: rows.length
|
|
2550
|
+
}
|
|
2551
|
+
),
|
|
2552
|
+
rows.length === 0 ? /* @__PURE__ */ jsx6(
|
|
2553
|
+
EmptyState,
|
|
2554
|
+
{
|
|
2555
|
+
icon: Puzzle,
|
|
2556
|
+
title: plugins.length === 0 ? t("plugins.manager.noneInstalled") : t("plugins.manager.nothingMatches")
|
|
2557
|
+
}
|
|
2558
|
+
) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2559
|
+
running.length > 0 && /* @__PURE__ */ jsx6(
|
|
2560
|
+
Group,
|
|
2240
2561
|
{
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2562
|
+
title: t("plugins.manager.groups.running"),
|
|
2563
|
+
count: running.length,
|
|
2564
|
+
children: collection(running)
|
|
2565
|
+
}
|
|
2566
|
+
),
|
|
2567
|
+
onServer.length > 0 && /* @__PURE__ */ jsx6(
|
|
2568
|
+
Group,
|
|
2569
|
+
{
|
|
2570
|
+
title: t("plugins.manager.groups.onServer"),
|
|
2571
|
+
count: onServer.length,
|
|
2572
|
+
children: collection(onServer)
|
|
2573
|
+
}
|
|
2574
|
+
),
|
|
2575
|
+
stopped.length > 0 && /* @__PURE__ */ jsx6(
|
|
2576
|
+
Group,
|
|
2577
|
+
{
|
|
2578
|
+
title: t("plugins.manager.groups.notRunning"),
|
|
2579
|
+
count: stopped.length,
|
|
2580
|
+
children: collection(stopped)
|
|
2249
2581
|
}
|
|
2250
2582
|
)
|
|
2251
2583
|
] })
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
EmptyState,
|
|
2256
|
-
{
|
|
2257
|
-
icon: Puzzle,
|
|
2258
|
-
title: plugins.length === 0 ? t("plugins.manager.noneInstalled") : t("plugins.manager.nothingMatches")
|
|
2259
|
-
}
|
|
2260
|
-
) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2261
|
-
running.length > 0 && /* @__PURE__ */ jsx6(
|
|
2262
|
-
Group,
|
|
2263
|
-
{
|
|
2264
|
-
title: t("plugins.manager.groups.running"),
|
|
2265
|
-
count: running.length,
|
|
2266
|
-
children: collection(running)
|
|
2267
|
-
}
|
|
2268
|
-
),
|
|
2269
|
-
onServer.length > 0 && /* @__PURE__ */ jsx6(
|
|
2270
|
-
Group,
|
|
2271
|
-
{
|
|
2272
|
-
title: t("plugins.manager.groups.onServer"),
|
|
2273
|
-
count: onServer.length,
|
|
2274
|
-
children: collection(onServer)
|
|
2275
|
-
}
|
|
2276
|
-
),
|
|
2277
|
-
stopped.length > 0 && /* @__PURE__ */ jsx6(
|
|
2278
|
-
Group,
|
|
2279
|
-
{
|
|
2280
|
-
title: t("plugins.manager.groups.notRunning"),
|
|
2281
|
-
count: stopped.length,
|
|
2282
|
-
children: collection(stopped)
|
|
2283
|
-
}
|
|
2284
|
-
)
|
|
2285
|
-
] })
|
|
2286
|
-
] });
|
|
2584
|
+
] })
|
|
2585
|
+
}
|
|
2586
|
+
);
|
|
2287
2587
|
}
|
|
2288
2588
|
function UploadButton({ manager }) {
|
|
2289
2589
|
const { t } = useTranslation7();
|
|
@@ -2570,31 +2870,49 @@ function BrowseSection({
|
|
|
2570
2870
|
layoutControls
|
|
2571
2871
|
}) {
|
|
2572
2872
|
const { t } = useTranslation7();
|
|
2573
|
-
const [
|
|
2574
|
-
const [registry, setRegistry] = useState5(null);
|
|
2873
|
+
const [facets, setFacets] = useState5(NO_FACETS);
|
|
2575
2874
|
const [sort, setSort] = useState5("popular");
|
|
2576
2875
|
const [installedChoice, setInstalledChoice] = useStoredChoice(
|
|
2577
2876
|
"pluginsTab.browseInstalled",
|
|
2578
2877
|
["hide", "show"],
|
|
2579
2878
|
"hide"
|
|
2580
2879
|
);
|
|
2880
|
+
const [unsupportedChoice, setUnsupportedChoice] = useStoredChoice(
|
|
2881
|
+
"pluginsTab.browseUnsupported",
|
|
2882
|
+
["hide", "show"],
|
|
2883
|
+
"hide"
|
|
2884
|
+
);
|
|
2885
|
+
const [pageSize, setPageSize] = useStoredChoice(
|
|
2886
|
+
"pluginsTab.pageSize",
|
|
2887
|
+
PAGE_SIZES,
|
|
2888
|
+
"24"
|
|
2889
|
+
);
|
|
2890
|
+
const scroller = useRef2(null);
|
|
2581
2891
|
const showInstalled = installedChoice === "show";
|
|
2582
|
-
const
|
|
2892
|
+
const showUnsupported = unsupportedChoice === "show";
|
|
2583
2893
|
const registries = manager.registries;
|
|
2584
|
-
const
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
),
|
|
2589
|
-
sort
|
|
2894
|
+
const unsupportedCount = plugins.filter(
|
|
2895
|
+
(p) => p.unsupported && !p.installed
|
|
2896
|
+
).length;
|
|
2897
|
+
const searched = plugins.filter(
|
|
2898
|
+
(p) => (showInstalled || !p.installed) && (showUnsupported || !p.unsupported || p.installed) && matchesQuery(p, query)
|
|
2590
2899
|
);
|
|
2900
|
+
const rows = sortPlugins(applyFacets(searched, facets), sort);
|
|
2901
|
+
const [page, setPage] = usePage(
|
|
2902
|
+
JSON.stringify([query, facets, sort, showInstalled, showUnsupported])
|
|
2903
|
+
);
|
|
2904
|
+
const paged = pageOf(rows, page, Number(pageSize));
|
|
2905
|
+
const goTo = (next) => {
|
|
2906
|
+
setPage(next);
|
|
2907
|
+
if (scroller.current) scroller.current.scrollTop = 0;
|
|
2908
|
+
};
|
|
2591
2909
|
const allInstalledHidden = !showInstalled && plugins.length > 0 && plugins.every((p) => p.installed);
|
|
2592
2910
|
const listColumns = [
|
|
2593
2911
|
{
|
|
2594
2912
|
key: "name",
|
|
2595
2913
|
header: t("plugins.manager.table.name"),
|
|
2596
2914
|
width: "minmax(0,1.3fr)",
|
|
2597
|
-
cell: (p) => /* @__PURE__ */ jsx6(NameCell, { plugin: p })
|
|
2915
|
+
cell: (p) => /* @__PURE__ */ jsx6(NameCell, { plugin: p, muted: p.unsupported })
|
|
2598
2916
|
},
|
|
2599
2917
|
{
|
|
2600
2918
|
key: "description",
|
|
@@ -2626,117 +2944,124 @@ function BrowseSection({
|
|
|
2626
2944
|
{
|
|
2627
2945
|
key: "actions",
|
|
2628
2946
|
header: "",
|
|
2629
|
-
width: "
|
|
2947
|
+
width: "150px",
|
|
2630
2948
|
align: "end",
|
|
2631
2949
|
cell: (p) => /* @__PURE__ */ jsx6(BrowseAction, { plugin: p, manager })
|
|
2632
2950
|
}
|
|
2633
2951
|
];
|
|
2634
|
-
return /* @__PURE__ */
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2952
|
+
return /* @__PURE__ */ jsx6(
|
|
2953
|
+
FilteredLayout,
|
|
2954
|
+
{
|
|
2955
|
+
activeCount: activeFacets(facets),
|
|
2956
|
+
scrollRef: scroller,
|
|
2957
|
+
rail: /* @__PURE__ */ jsxs6(
|
|
2958
|
+
FilterRail,
|
|
2959
|
+
{
|
|
2960
|
+
rows: searched,
|
|
2961
|
+
facets,
|
|
2962
|
+
onFacets: setFacets,
|
|
2963
|
+
registries,
|
|
2964
|
+
children: [
|
|
2644
2965
|
/* @__PURE__ */ jsx6(
|
|
2645
|
-
|
|
2966
|
+
RailToggle,
|
|
2646
2967
|
{
|
|
2968
|
+
label: t("plugins.manager.showInstalled"),
|
|
2647
2969
|
checked: showInstalled,
|
|
2648
2970
|
onChange: (v) => setInstalledChoice(v ? "show" : "hide")
|
|
2649
2971
|
}
|
|
2972
|
+
),
|
|
2973
|
+
unsupportedCount > 0 && /* @__PURE__ */ jsx6(
|
|
2974
|
+
RailToggle,
|
|
2975
|
+
{
|
|
2976
|
+
label: t("plugins.manager.showUnsupported", {
|
|
2977
|
+
count: unsupportedCount
|
|
2978
|
+
}),
|
|
2979
|
+
hint: t("plugins.manager.showUnsupportedHint"),
|
|
2980
|
+
checked: showUnsupported,
|
|
2981
|
+
onChange: (v) => setUnsupportedChoice(v ? "show" : "hide")
|
|
2982
|
+
}
|
|
2650
2983
|
)
|
|
2651
|
-
]
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
),
|
|
2670
|
-
/* @__PURE__ */ jsxs6(SelectContent, { children: [
|
|
2671
|
-
/* @__PURE__ */ jsx6(SelectItem, { value: "__all", className: "text-xs", children: t("plugins.manager.registries.allRegistries") }),
|
|
2672
|
-
registries.map((entry) => /* @__PURE__ */ jsx6(
|
|
2673
|
-
SelectItem,
|
|
2674
|
-
{
|
|
2675
|
-
value: entry.id,
|
|
2676
|
-
className: "text-xs",
|
|
2677
|
-
children: entry.name
|
|
2678
|
-
},
|
|
2679
|
-
entry.id
|
|
2680
|
-
))
|
|
2681
|
-
] })
|
|
2682
|
-
]
|
|
2683
|
-
}
|
|
2684
|
-
),
|
|
2685
|
-
/* @__PURE__ */ jsx6(SortSelect, { value: sort, onChange: setSort }),
|
|
2686
|
-
layoutControls
|
|
2687
|
-
] })
|
|
2688
|
-
}
|
|
2689
|
-
),
|
|
2690
|
-
categories.length > 0 && /* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-1", children: [null, ...categories].map((c) => /* @__PURE__ */ jsx6(
|
|
2691
|
-
"button",
|
|
2692
|
-
{
|
|
2693
|
-
type: "button",
|
|
2694
|
-
onClick: () => setCategory(c),
|
|
2695
|
-
className: cn(
|
|
2696
|
-
"border px-2 py-1 text-[11px] font-medium transition-colors",
|
|
2697
|
-
category === c ? "border-accent-brand bg-accent-brand/10 text-accent-brand" : "border-border text-muted-foreground hover:text-foreground"
|
|
2984
|
+
]
|
|
2985
|
+
}
|
|
2986
|
+
),
|
|
2987
|
+
children: (filtersButton) => /* @__PURE__ */ jsxs6("div", { className: `flex flex-col ${PANEL.gap} ${PANEL.body}`, children: [
|
|
2988
|
+
/* @__PURE__ */ jsxs6(
|
|
2989
|
+
Toolbar,
|
|
2990
|
+
{
|
|
2991
|
+
query,
|
|
2992
|
+
onQuery,
|
|
2993
|
+
placeholder: t("plugins.manager.searchPlugins"),
|
|
2994
|
+
children: [
|
|
2995
|
+
filtersButton,
|
|
2996
|
+
/* @__PURE__ */ jsxs6("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
2997
|
+
/* @__PURE__ */ jsx6(SortSelect, { value: sort, onChange: setSort }),
|
|
2998
|
+
layoutControls
|
|
2999
|
+
] })
|
|
3000
|
+
]
|
|
3001
|
+
}
|
|
2698
3002
|
),
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
c ?? "__all"
|
|
2702
|
-
)) }),
|
|
2703
|
-
rows.length === 0 ? allInstalledHidden ? /* @__PURE__ */ jsx6(
|
|
2704
|
-
EmptyState,
|
|
2705
|
-
{
|
|
2706
|
-
icon: Puzzle,
|
|
2707
|
-
title: t("plugins.manager.allInstalled"),
|
|
2708
|
-
hint: t("plugins.manager.allInstalledHint")
|
|
2709
|
-
}
|
|
2710
|
-
) : /* @__PURE__ */ jsx6(
|
|
2711
|
-
EmptyState,
|
|
2712
|
-
{
|
|
2713
|
-
icon: Puzzle,
|
|
2714
|
-
title: t("plugins.manager.nothingHere"),
|
|
2715
|
-
hint: plugins.length === 0 ? void 0 : t("plugins.manager.nothingHereHint")
|
|
2716
|
-
}
|
|
2717
|
-
) : /* @__PURE__ */ jsx6(
|
|
2718
|
-
PluginCollection,
|
|
2719
|
-
{
|
|
2720
|
-
plugins: rows,
|
|
2721
|
-
layout,
|
|
2722
|
-
renderCard: (p) => /* @__PURE__ */ jsx6(
|
|
2723
|
-
BrowseCard,
|
|
3003
|
+
/* @__PURE__ */ jsx6(
|
|
3004
|
+
ActiveFilters,
|
|
2724
3005
|
{
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
3006
|
+
facets,
|
|
3007
|
+
onFacets: setFacets,
|
|
3008
|
+
registries,
|
|
3009
|
+
shown: rows.length
|
|
2728
3010
|
}
|
|
2729
3011
|
),
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
3012
|
+
rows.length === 0 ? allInstalledHidden ? /* @__PURE__ */ jsx6(
|
|
3013
|
+
EmptyState,
|
|
3014
|
+
{
|
|
3015
|
+
icon: Puzzle,
|
|
3016
|
+
title: t("plugins.manager.allInstalled"),
|
|
3017
|
+
hint: t("plugins.manager.allInstalledHint")
|
|
3018
|
+
}
|
|
3019
|
+
) : /* @__PURE__ */ jsx6(
|
|
3020
|
+
EmptyState,
|
|
3021
|
+
{
|
|
3022
|
+
icon: Puzzle,
|
|
3023
|
+
title: t("plugins.manager.nothingHere"),
|
|
3024
|
+
hint: plugins.length === 0 ? void 0 : t("plugins.manager.nothingHereHint")
|
|
3025
|
+
}
|
|
3026
|
+
) : /* @__PURE__ */ jsx6(
|
|
3027
|
+
PluginCollection,
|
|
3028
|
+
{
|
|
3029
|
+
plugins: paged.items,
|
|
3030
|
+
layout,
|
|
3031
|
+
renderCard: (p) => /* @__PURE__ */ jsx6(
|
|
3032
|
+
BrowseCard,
|
|
3033
|
+
{
|
|
3034
|
+
plugin: p,
|
|
3035
|
+
manager,
|
|
3036
|
+
onOpen: () => onOpen(p.id)
|
|
3037
|
+
}
|
|
3038
|
+
),
|
|
3039
|
+
listColumns,
|
|
3040
|
+
onOpen
|
|
3041
|
+
}
|
|
3042
|
+
),
|
|
3043
|
+
/* @__PURE__ */ jsx6(
|
|
3044
|
+
Pager,
|
|
3045
|
+
{
|
|
3046
|
+
page: paged.page,
|
|
3047
|
+
pages: paged.pages,
|
|
3048
|
+
total: rows.length,
|
|
3049
|
+
size: pageSize,
|
|
3050
|
+
onPage: goTo,
|
|
3051
|
+
onSize: (next) => {
|
|
3052
|
+
setPageSize(next);
|
|
3053
|
+
goTo(1);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
),
|
|
3057
|
+
/* @__PURE__ */ jsxs6("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
3058
|
+
t("plugins.manager.registries.browseHint"),
|
|
3059
|
+
" ",
|
|
3060
|
+
/* @__PURE__ */ jsx6(DocsLink, { core: "communityRegistry", className: "text-[11px]", children: t("plugins.manager.communitySubmit") })
|
|
3061
|
+
] })
|
|
3062
|
+
] })
|
|
3063
|
+
}
|
|
3064
|
+
);
|
|
2740
3065
|
}
|
|
2741
3066
|
function BrowseCard({
|
|
2742
3067
|
plugin,
|
|
@@ -2750,6 +3075,7 @@ function BrowseCard({
|
|
|
2750
3075
|
CardHead,
|
|
2751
3076
|
{
|
|
2752
3077
|
plugin,
|
|
3078
|
+
muted: plugin.unsupported,
|
|
2753
3079
|
onOpen,
|
|
2754
3080
|
facts: /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2755
3081
|
/* @__PURE__ */ jsx6(
|
|
@@ -2770,7 +3096,7 @@ function BrowseCard({
|
|
|
2770
3096
|
}
|
|
2771
3097
|
),
|
|
2772
3098
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 border-t border-border px-3 py-2", children: [
|
|
2773
|
-
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate text-[10px] text-muted-foreground", children: severe.length > 0 ? t(`plugins.capabilities.${severe[0]}.title`, {
|
|
3099
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate text-[10px] text-muted-foreground", children: plugin.unsupported && !plugin.installed ? "" : severe.length > 0 ? t(`plugins.capabilities.${severe[0]}.title`, {
|
|
2774
3100
|
defaultValue: severe[0],
|
|
2775
3101
|
nsSeparator: false
|
|
2776
3102
|
}) : t("plugins.manager.noServerAccess") }),
|
|
@@ -2794,7 +3120,14 @@ function BrowseAction({
|
|
|
2794
3120
|
plugin.installed ? /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1 text-[11px] font-medium text-accent-brand", children: [
|
|
2795
3121
|
/* @__PURE__ */ jsx6(Check, { className: "size-3" }),
|
|
2796
3122
|
t("plugins.manager.installedBadge")
|
|
2797
|
-
] }) : /* @__PURE__ */ jsx6(
|
|
3123
|
+
] }) : plugin.unsupported ? /* @__PURE__ */ jsx6(
|
|
3124
|
+
"span",
|
|
3125
|
+
{
|
|
3126
|
+
className: "shrink-0 text-[11px] text-muted-foreground",
|
|
3127
|
+
title: t("plugins.manager.unsupportedHint"),
|
|
3128
|
+
children: plugin.needsTermix ? t("plugins.manager.needsTermix", { range: plugin.needsTermix }) : t("plugins.manager.unsupported")
|
|
3129
|
+
}
|
|
3130
|
+
) : /* @__PURE__ */ jsx6(
|
|
2798
3131
|
Button,
|
|
2799
3132
|
{
|
|
2800
3133
|
variant: "outline",
|