mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-11-07 02:55:24 +00:00
feat: shared tile look for cards and pages, plus new page pieces in SDK 1.1.0
This commit is contained in:
1 parent
1867be3f58
commit
19bdd589f3
41 files changed
+1497
-207
No files matched your search
@@ -17,8 +17,9 @@ import {
|
||||
TriangleAlert,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/button";
|
||||
import { Card } from "@/components/card";
|
||||
import { Facts, PANEL } from "@/components/panel-layout";
|
||||
import { Facts } from "@/components/panel-layout";
|
||||
import { TileStack } from "@/components/tile-grid/TileStack";
|
||||
import { TileWall } from "@/components/tile-grid/TileWall";
|
||||
import { FakeSwitch, SectionCard } from "@/components/section-card";
|
||||
import {
|
||||
Select,
|
||||
@@ -52,7 +53,7 @@ import { PluginReleaseNotes, PluginVideo } from "./PluginReleaseNotes";
|
||||
import type { PluginsManager } from "./use-plugins-manager";
|
||||
|
||||
const LINK_ROW =
|
||||
"flex items-center gap-2 border border-border bg-card px-3 py-2.5 text-left text-[11px] text-muted-foreground transition-colors hover:border-accent-brand/40 hover:text-foreground";
|
||||
"flex w-full items-center gap-2 px-3 py-2.5 text-left text-[11px] text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground";
|
||||
|
||||
export function PluginDetail({
|
||||
plugin,
|
||||
@@ -93,10 +94,8 @@ export function PluginDetail({
|
||||
const tryableBeta = betaToTry(plugin);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`mx-auto flex w-full max-w-5xl flex-col ${PANEL.gap} ${PANEL.body}`}
|
||||
>
|
||||
<Card className="flex-row flex-wrap items-start gap-4 px-4 py-4">
|
||||
<TileStack>
|
||||
<div className="flex flex-row flex-wrap items-start gap-3 p-3">
|
||||
<PluginIconBox
|
||||
name={plugin.icon}
|
||||
size="lg"
|
||||
@@ -223,10 +222,10 @@ export function PluginDetail({
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{plugin.installed && failed && plugin.lastError && (
|
||||
<div className="flex items-start gap-2 border border-destructive/30 bg-destructive/5 px-3 py-2.5">
|
||||
<div className="flex items-start gap-2 bg-destructive/5 px-3 py-2.5">
|
||||
<TriangleAlert className="mt-px size-3.5 shrink-0 text-destructive" />
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<span className="text-xs font-medium">
|
||||
@@ -242,7 +241,7 @@ export function PluginDetail({
|
||||
)}
|
||||
|
||||
{plugin.status === "server" && (
|
||||
<div className="flex items-start gap-2 border border-border bg-muted/30 px-3 py-2.5">
|
||||
<div className="flex items-start gap-2 bg-muted/30 px-3 py-2.5">
|
||||
<Server className="mt-px size-3.5 shrink-0 text-muted-foreground" />
|
||||
<span className="text-[11px] leading-snug text-muted-foreground">
|
||||
{t("plugins.manager.runsOnServerHint")}
|
||||
@@ -250,13 +249,13 @@ export function PluginDetail({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-1 gap-2 lg:grid-cols-3">
|
||||
<div className="flex flex-col gap-2 lg:col-span-2">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3">
|
||||
<TileStack className="-mb-px border-border lg:col-span-2 lg:border-r">
|
||||
<PluginVideo videoId={plugin.videoId} name={plugin.name} />
|
||||
|
||||
{plugin.features.length > 0 && (
|
||||
<SectionCard title={t("plugins.manager.features")} icon={null}>
|
||||
<ul className="grid grid-cols-1 gap-x-4 gap-y-1.5 px-4 py-3 sm:grid-cols-2">
|
||||
<ul className="grid grid-cols-1 gap-x-4 gap-y-1.5 py-3 sm:grid-cols-2">
|
||||
{plugin.features.map((feature) => (
|
||||
<li
|
||||
key={feature}
|
||||
@@ -277,11 +276,11 @@ export function PluginDetail({
|
||||
key={capability}
|
||||
capability={capability}
|
||||
showId
|
||||
className="px-4 py-2.5"
|
||||
className="py-2.5"
|
||||
/>
|
||||
))}
|
||||
{plugin.capabilities.length === 0 && (
|
||||
<div className="px-4 py-2.5 text-[11px] text-muted-foreground">
|
||||
<div className="py-2.5 text-[11px] text-muted-foreground">
|
||||
{t("plugins.manager.consent.none")}
|
||||
</div>
|
||||
)}
|
||||
@@ -292,10 +291,7 @@ export function PluginDetail({
|
||||
<SectionCard title={t("plugins.manager.envVars")} icon={null}>
|
||||
<div className="divide-y divide-border">
|
||||
{plugin.env.map((v) => (
|
||||
<div
|
||||
key={v.name}
|
||||
className="flex flex-col gap-0.5 px-4 py-2.5"
|
||||
>
|
||||
<div key={v.name} className="flex flex-col gap-0.5 py-2.5">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<code className="font-mono text-xs font-semibold">
|
||||
{v.name}
|
||||
@@ -331,12 +327,12 @@ export function PluginDetail({
|
||||
onDelete={() => manager.removeData(plugin)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</TileStack>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<TileStack className="-mb-px">
|
||||
{contributions.length > 0 && (
|
||||
<SectionCard title={t("plugins.manager.addsToTermix")} icon={null}>
|
||||
<div className="flex flex-col gap-2 px-4 py-3">
|
||||
<div className="flex flex-col gap-2 py-3">
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{contributions.map((c) => (
|
||||
<span
|
||||
@@ -358,7 +354,7 @@ export function PluginDetail({
|
||||
|
||||
{plugin.inRegistry && compatible.length > 0 && (
|
||||
<SectionCard title={t("plugins.manager.version")} icon={null}>
|
||||
<div className="flex flex-col gap-2 px-4 py-3">
|
||||
<div className="flex flex-col gap-2 py-3">
|
||||
<span className="text-[11px] leading-snug text-muted-foreground">
|
||||
{plugin.installed
|
||||
? t("plugins.manager.versionPickHintInstalled")
|
||||
@@ -414,7 +410,7 @@ export function PluginDetail({
|
||||
{plugin.installed && (
|
||||
<SectionCard title={t("plugins.manager.updates")} icon={null}>
|
||||
<div className="divide-y divide-border">
|
||||
<div className="flex items-center justify-between gap-3 px-4 py-3">
|
||||
<div className="flex items-center justify-between gap-3 py-3">
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<span className="text-xs font-medium">
|
||||
{t("plugins.manager.autoUpdate")}
|
||||
@@ -431,7 +427,7 @@ export function PluginDetail({
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-3 px-4 py-3">
|
||||
<div className="flex items-center justify-between gap-3 py-3">
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<span className="flex items-center gap-1.5 text-xs font-medium">
|
||||
<FlaskConical className="size-3 text-muted-foreground" />
|
||||
@@ -455,7 +451,7 @@ export function PluginDetail({
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-3 px-4 py-3">
|
||||
<div className="flex items-center justify-between gap-3 py-3">
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<span className="flex items-center gap-1.5 text-xs font-medium">
|
||||
<Pin className="size-3 text-muted-foreground" />
|
||||
@@ -565,9 +561,9 @@ export function PluginDetail({
|
||||
</span>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</TileStack>
|
||||
</div>
|
||||
</div>
|
||||
</TileStack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -625,16 +621,16 @@ function DataCard({
|
||||
}
|
||||
>
|
||||
{error ? (
|
||||
<div className="px-4 py-3 text-[11px] text-muted-foreground">
|
||||
<div className="py-3 text-[11px] text-muted-foreground">
|
||||
{t("plugins.manager.data.loadFailed")}
|
||||
</div>
|
||||
) : !data ? (
|
||||
<div className="px-4 py-3 text-[11px] text-muted-foreground">
|
||||
<div className="py-3 text-[11px] text-muted-foreground">
|
||||
{t("plugins.manager.loading")}
|
||||
</div>
|
||||
) : (
|
||||
<div className="-mx-3 -my-1 flex flex-col md:-mx-4">
|
||||
<div className="grid grid-cols-2 gap-px bg-border sm:grid-cols-4">
|
||||
<div className="-mx-3 -my-1 flex flex-col">
|
||||
<TileWall gridClassName="grid-cols-2 sm:grid-cols-4">
|
||||
<Stat
|
||||
label={t("plugins.manager.data.tables")}
|
||||
value={`${data.tables.length}`}
|
||||
@@ -655,13 +651,13 @@ function DataCard({
|
||||
label={t("plugins.manager.data.files")}
|
||||
value={formatBytes(data.filesBytes)}
|
||||
/>
|
||||
</div>
|
||||
</TileWall>
|
||||
{data.tables.length > 0 && (
|
||||
<div className="divide-y divide-border border-t border-border">
|
||||
{data.tables.map((table) => (
|
||||
<div
|
||||
key={table.name}
|
||||
className="flex items-center gap-2 px-4 py-1.5"
|
||||
className="flex items-center gap-2 px-3 py-1.5"
|
||||
>
|
||||
<span className="min-w-0 flex-1 truncate font-mono text-[11px]">
|
||||
{table.name}
|
||||
@@ -675,7 +671,7 @@ function DataCard({
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-1 border-t border-border px-4 py-2 text-[11px] text-muted-foreground">
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-1 border-t border-border py-2 text-[11px] text-muted-foreground">
|
||||
<span>
|
||||
{t("plugins.manager.data.migrations", {
|
||||
count: data.migrations.length,
|
||||
@@ -701,7 +697,7 @@ function Stat({
|
||||
hint?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col gap-0.5 bg-card px-4 py-2.5">
|
||||
<div className="flex flex-col gap-0.5 px-3 py-2.5">
|
||||
<span className="text-[10px] font-semibold uppercase tracking-widest text-muted-foreground">
|
||||
{label}
|
||||
</span>
|
||||
|
||||
Reference in new issue
Block a user