refactor: 根级 src/src-tauri/server 布局 + 设置左导航搜索 + 语言切换 + DataGrip 高亮 + 断连横幅移除
This commit is contained in:
1 parent
456fa6954b
commit
b3542cb458
32 files changed
+148
-58
No files matched your search
+26
-7
@@ -82,6 +82,7 @@ export function SettingsModal({ onClose }: { onClose: () => void }) {
|
||||
const openConnectionList = useWorkspaceStore((s) => s.openConnectionList);
|
||||
|
||||
const [drivers, setDrivers] = useState<DriverStatusItem[] | null>(null);
|
||||
const [navSearch, setNavSearch] = useState("");
|
||||
const [version, setVersion] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
@@ -99,19 +100,37 @@ export function SettingsModal({ onClose }: { onClose: () => void }) {
|
||||
return (
|
||||
<OpsModal variant="info" title="设置" onOk={onClose}>
|
||||
<div className="flex" style={{ minWidth: 560, minHeight: 340 }}>
|
||||
{/* 左导航 */}
|
||||
<nav className="w-36 shrink-0 space-y-px border-r pr-1" style={{ borderColor: "var(--ops-border-soft)" }}>
|
||||
{TABS.map((t) => (
|
||||
{/* 左导航:搜索 + 图标主标题 + 副文案(对齐 opsxshell 质感) */}
|
||||
<nav className="w-52 shrink-0 border-r pr-1" style={{ borderColor: "var(--ops-border-soft)" }}>
|
||||
<input
|
||||
className="ops-input mb-2 h-7 w-full text-[12px]"
|
||||
placeholder="搜索设置…"
|
||||
value={navSearch}
|
||||
onChange={(e) => setNavSearch(e.target.value)}
|
||||
/>
|
||||
{TABS.filter((t) => {
|
||||
const q = navSearch.trim().toLowerCase();
|
||||
if (!q) return true;
|
||||
return (t.label + t.desc).toLowerCase().includes(q);
|
||||
}).map((t) => (
|
||||
<button
|
||||
key={t.id}
|
||||
type="button"
|
||||
className={`flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-[12px] transition ${
|
||||
tab === t.id ? "ops-tree-item-active font-medium" : "opacity-70 hover:opacity-100"
|
||||
className={`flex w-full items-center gap-2 rounded px-2 py-2 text-left transition ${
|
||||
tab === t.id
|
||||
? "bg-[color-mix(in_srgb,var(--ops-accent)_12%,transparent)]"
|
||||
: "opacity-75 hover:opacity-100"
|
||||
}`}
|
||||
style={tab === t.id ? { boxShadow: "inset 2px 0 0 var(--ops-accent)" } : undefined}
|
||||
onClick={() => setTab(t.id)}
|
||||
>
|
||||
<span className="w-4 text-center">{t.icon}</span>
|
||||
<span>{t.label}</span>
|
||||
<span className="w-4 text-center text-[13px]" style={tab === t.id ? { color: "var(--ops-accent)" } : { color: "var(--ops-muted)" }}>
|
||||
{t.icon}
|
||||
</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block text-[12px] font-medium">{t.label}</span>
|
||||
<span className="block text-[10px]" style={{ color: "var(--ops-muted)" }}>{t.desc}</span>
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
+15
-15
@@ -58,27 +58,27 @@ function redisComplete(ctx: CompletionContext): CompletionResult | null {
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL 高亮走克制的四色方案(VS Code Dark+ 观感):
|
||||
* 关键字+数字 = 蓝,字符串 = 橙,注释 = 绿,标识符/运算符 = 前景浅白。
|
||||
* 注册在 oneDark 之后,覆盖其默认的五彩配色。
|
||||
* SQL 高亮:DataGrip Dark 风格(用户点单对照截图)——
|
||||
* 关键字 = 亮蓝加粗,字符串 = 红,数字 = 浅绿,标识符 = 浅灰白,注释 = 灰斜体。
|
||||
* 注册在 oneDark 之后,覆盖其默认配色。
|
||||
*/
|
||||
const sqlDarkHighlight = HighlightStyle.define([
|
||||
{ tag: [t.keyword, t.controlKeyword, t.moduleKeyword, t.operatorKeyword, t.definitionKeyword], color: "#569CD6" },
|
||||
{ tag: [t.number, t.integer, t.bool, t.null, t.atom], color: "#569CD6" },
|
||||
{ tag: [t.string, t.special(t.string)], color: "#CE9178" },
|
||||
{ tag: [t.lineComment, t.blockComment, t.docComment], color: "#6A9955" },
|
||||
{ tag: [t.variableName, t.typeName, t.propertyName, t.operator, t.punctuation, t.definition(t.variableName)], color: "#D4D4D4" },
|
||||
{ tag: [t.function(t.variableName), t.function(t.propertyName)], color: "#D4D4D4" },
|
||||
{ tag: [t.keyword, t.controlKeyword, t.moduleKeyword, t.operatorKeyword, t.definitionKeyword], color: "#39A5FF", fontWeight: "700" },
|
||||
{ tag: [t.number, t.integer, t.bool, t.null, t.atom], color: "#98C379" },
|
||||
{ tag: [t.string, t.special(t.string)], color: "#E06C75" },
|
||||
{ tag: [t.lineComment, t.blockComment, t.docComment], color: "#7A7A7A", fontStyle: "italic" },
|
||||
{ tag: [t.variableName, t.typeName, t.propertyName, t.operator, t.punctuation, t.definition(t.variableName)], color: "#A9B7C6" },
|
||||
{ tag: [t.function(t.variableName), t.function(t.propertyName)], color: "#E8E8E8" },
|
||||
]);
|
||||
|
||||
/** 浅色主题四色方案:关键字蓝、字符串枣红、注释绿、标识符近黑 */
|
||||
const sqlLightHighlight = HighlightStyle.define([
|
||||
{ tag: [t.keyword, t.controlKeyword, t.moduleKeyword, t.operatorKeyword, t.definitionKeyword], color: "#0000FF" },
|
||||
{ tag: [t.number, t.integer, t.bool, t.null, t.atom], color: "#0000FF" },
|
||||
{ tag: [t.string, t.special(t.string)], color: "#A31515" },
|
||||
{ tag: [t.lineComment, t.blockComment, t.docComment], color: "#008000" },
|
||||
{ tag: [t.variableName, t.typeName, t.propertyName, t.operator, t.punctuation, t.definition(t.variableName)], color: "#24292F" },
|
||||
{ tag: [t.function(t.variableName), t.function(t.propertyName)], color: "#24292F" },
|
||||
{ tag: [t.keyword, t.controlKeyword, t.moduleKeyword, t.operatorKeyword, t.definitionKeyword], color: "#0033B3", fontWeight: "700" },
|
||||
{ tag: [t.number, t.integer, t.bool, t.null, t.atom], color: "#1750EB" },
|
||||
{ tag: [t.string, t.special(t.string)], color: "#067D17" },
|
||||
{ tag: [t.lineComment, t.blockComment, t.docComment], color: "#8C8C8C", fontStyle: "italic" },
|
||||
{ tag: [t.variableName, t.typeName, t.propertyName, t.operator, t.punctuation, t.definition(t.variableName)], color: "#000000" },
|
||||
{ tag: [t.function(t.variableName), t.function(t.propertyName)], color: "#000000" },
|
||||
]);
|
||||
|
||||
export type SqlEditorHandle = {
|
||||
|
||||
@@ -1365,7 +1365,6 @@ export function OpsxWorkspace() {
|
||||
const activeConnectionId = useWorkspaceStore((s) => s.activeConnectionId);
|
||||
const connections = useWorkspaceStore((s) => s.connections);
|
||||
const connState = useWorkspaceStore((s) => s.connState);
|
||||
const [dismissDown, setDismissDown] = useState(false);
|
||||
const conn = useWorkspaceStore((s) => s.connections.find((c) => c.id === s.activeConnectionId)); const set = useWorkspaceStore((s) => s.set);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -1498,7 +1497,6 @@ export function OpsxWorkspace() {
|
||||
|
||||
// 新断开时重新显示提示(用户上次关闭后,再次断开要能看见)。必须位于 view 早退之前,否则切到选择器视图时 hooks 数量变化会崩溃。
|
||||
useEffect(() => {
|
||||
if (connState === "down") setDismissDown(false);
|
||||
}, [connState]);
|
||||
|
||||
if (view === "picker") {
|
||||
@@ -1515,28 +1513,6 @@ export function OpsxWorkspace() {
|
||||
<div className="ops-shell flex h-screen min-h-[640px] flex-col">
|
||||
<TopNav />
|
||||
{launchStrip}
|
||||
{connState === "down" && !dismissDown && (
|
||||
<div
|
||||
className="flex shrink-0 items-center gap-2 border-b px-2.5 text-[11px]"
|
||||
style={{
|
||||
height: 28,
|
||||
borderColor: "color-mix(in srgb, var(--ops-danger) 35%, var(--ops-border))",
|
||||
background: "color-mix(in srgb, var(--ops-danger) 8%, transparent)",
|
||||
color: "var(--ops-danger)",
|
||||
}}
|
||||
>
|
||||
<span>⚠ {conn ? `${conn.name} 已断开` : "连接已断开"}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="ml-auto px-1 text-[13px] leading-none"
|
||||
style={{ color: "var(--ops-muted)" }}
|
||||
title="关闭提示"
|
||||
onClick={() => setDismissDown(true)}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex min-h-0 flex-1">
|
||||
<aside className="ops-panel flex h-full shrink-0 flex-col border-r" style={{ width: leftWidth }}>
|
||||
<div className="min-h-0 flex-1 overflow-auto">
|
||||
|
||||
Reference in new issue
Block a user