Skip to content

Commit a2e6f7b

Browse files
authored
Remove Config Errors from TabBar, move to Settings / WaveConfig (#3060)
1 parent d0a5c29 commit a2e6f7b

File tree

5 files changed

+254
-186
lines changed

5 files changed

+254
-186
lines changed

frontend/app/tab/tabbar.tsx

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import { Tooltip } from "@/app/element/tooltip";
5-
import { modalsModel } from "@/app/store/modalmodel";
65
import { TabRpcClient } from "@/app/store/wshrpcutil";
76
import { useWaveEnv } from "@/app/waveenv/waveenv";
87
import { WorkspaceLayoutModel } from "@/app/workspace/workspace-layout-model";
@@ -76,68 +75,6 @@ const WaveAIButton = memo(({ divRef }: { divRef?: React.RefObject<HTMLDivElement
7675
});
7776
WaveAIButton.displayName = "WaveAIButton";
7877

79-
const ConfigErrorMessage = () => {
80-
const env = useWaveEnv<TabBarEnv>();
81-
const fullConfig = useAtomValue(env.atoms.fullConfigAtom);
82-
83-
if (fullConfig?.configerrors == null || fullConfig?.configerrors.length == 0) {
84-
return (
85-
<div className="max-w-[500px] p-5">
86-
<h3 className="font-bold text-base mb-2.5">Configuration Clean</h3>
87-
<p>There are no longer any errors detected in your config.</p>
88-
</div>
89-
);
90-
}
91-
if (fullConfig?.configerrors.length == 1) {
92-
const singleError = fullConfig.configerrors[0];
93-
return (
94-
<div className="max-w-[500px] p-5">
95-
<h3 className="font-bold text-base mb-2.5">Configuration Error</h3>
96-
<div>
97-
{singleError.file}: {singleError.err}
98-
</div>
99-
</div>
100-
);
101-
}
102-
return (
103-
<div className="max-w-[500px] p-5">
104-
<h3 className="font-bold text-base mb-2.5">Configuration Error</h3>
105-
<ul>
106-
{fullConfig.configerrors.map((error, index) => (
107-
<li key={index}>
108-
{error.file}: {error.err}
109-
</li>
110-
))}
111-
</ul>
112-
</div>
113-
);
114-
};
115-
116-
const ConfigErrorIcon = () => {
117-
const env = useWaveEnv<TabBarEnv>();
118-
const hasConfigErrors = useAtomValue(env.atoms.hasConfigErrors);
119-
120-
const handleClick = useCallback(() => {
121-
modalsModel.pushModal("MessageModal", { children: <ConfigErrorMessage /> });
122-
}, []);
123-
124-
if (!hasConfigErrors) {
125-
return null;
126-
}
127-
return (
128-
<Tooltip
129-
content="Configuration Error"
130-
placement="bottom"
131-
hideOnClick
132-
divClassName="flex h-[22px] px-2 mb-1 items-center rounded-md box-border cursor-pointer hover:bg-hoverbg transition-colors text-[12px] text-error"
133-
divStyle={{ WebkitAppRegion: "no-drag" } as React.CSSProperties}
134-
divOnClick={handleClick}
135-
>
136-
<i className="fa fa-solid fa-triangle-exclamation" />
137-
</Tooltip>
138-
);
139-
};
140-
14178
function strArrayIsEqual(a: string[], b: string[]) {
14279
// null check
14380
if (a == null && b == null) {
@@ -197,7 +134,6 @@ const TabBar = memo(({ workspace, noTabs }: TabBarProps) => {
197134
const confirmClose = useAtomValue(env.getSettingsKeyAtom("tab:confirmclose")) ?? false;
198135
const hideAiButton = useAtomValue(env.getSettingsKeyAtom("app:hideaibutton"));
199136
const appUpdateStatus = useAtomValue(env.atoms.updaterStatusAtom);
200-
const hasConfigErrors = useAtomValue(env.atoms.hasConfigErrors);
201137

202138
let prevDelta: number;
203139
let prevDragDirection: string;
@@ -335,7 +271,7 @@ const TabBar = memo(({ workspace, noTabs }: TabBarProps) => {
335271
};
336272
}, [handleResizeTabs]);
337273

338-
// update layout on changed tabIds, tabsLoaded, newTabId, hideAiButton, appUpdateStatus, hasConfigErrors, or zoomFactor
274+
// update layout on changed tabIds, tabsLoaded, newTabId, hideAiButton, appUpdateStatus, or zoomFactor
339275
useEffect(() => {
340276
// Check if all tabs are loaded
341277
const allLoaded = tabIds.length > 0 && tabIds.every((id) => tabsLoaded[id]);
@@ -353,7 +289,6 @@ const TabBar = memo(({ workspace, noTabs }: TabBarProps) => {
353289
saveTabsPosition,
354290
hideAiButton,
355291
appUpdateStatus,
356-
hasConfigErrors,
357292
zoomFactor,
358293
showMenuBar,
359294
]);
@@ -731,7 +666,6 @@ const TabBar = memo(({ workspace, noTabs }: TabBarProps) => {
731666
<div className="flex-1" />
732667
<div ref={rightContainerRef} className="flex flex-row gap-1 items-end">
733668
<UpdateStatusBanner />
734-
<ConfigErrorIcon />
735669
<div
736670
className="h-full shrink-0 z-window-drag"
737671
style={{ width: windowDragRightWidth, WebkitAppRegion: "drag" } as any}
@@ -741,4 +675,4 @@ const TabBar = memo(({ workspace, noTabs }: TabBarProps) => {
741675
);
742676
});
743677

744-
export { ConfigErrorIcon, ConfigErrorMessage, TabBar, WaveAIButton };
678+
export { TabBar, WaveAIButton };

frontend/app/view/waveconfig/waveconfig-model.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import { BlockNodeModel } from "@/app/block/blocktypes";
5-
import { getApi, getBlockMetaKeyAtom, WOS } from "@/app/store/global";
5+
import { atoms, getApi, getBlockMetaKeyAtom, WOS } from "@/app/store/global";
66
import { globalStore } from "@/app/store/jotaiStore";
77
import type { TabModel } from "@/app/store/tab-model";
88
import { RpcApi } from "@/app/store/wshclientapi";
@@ -11,7 +11,7 @@ import { SecretsContent } from "@/app/view/waveconfig/secretscontent";
1111
import { WaveConfigView } from "@/app/view/waveconfig/waveconfig";
1212
import { isWindows } from "@/util/platformutil";
1313
import { base64ToString, stringToBase64 } from "@/util/util";
14-
import { atom, type PrimitiveAtom } from "jotai";
14+
import { atom, type Atom, type PrimitiveAtom } from "jotai";
1515
import type * as MonacoTypes from "monaco-editor";
1616
import * as React from "react";
1717

@@ -156,6 +156,7 @@ export class WaveConfigViewModel implements ViewModel {
156156
isMenuOpenAtom: PrimitiveAtom<boolean>;
157157
presetsJsonExistsAtom: PrimitiveAtom<boolean>;
158158
activeTabAtom: PrimitiveAtom<"visual" | "json">;
159+
configErrorFilesAtom: Atom<Set<string>>;
159160
configDir: string;
160161
saveShortcut: string;
161162
editorRef: React.RefObject<MonacoTypes.editor.IStandaloneCodeEditor>;
@@ -189,6 +190,14 @@ export class WaveConfigViewModel implements ViewModel {
189190
this.isMenuOpenAtom = atom(false);
190191
this.presetsJsonExistsAtom = atom(false);
191192
this.activeTabAtom = atom<"visual" | "json">("visual");
193+
this.configErrorFilesAtom = atom((get) => {
194+
const fullConfig = get(atoms.fullConfigAtom);
195+
const errorSet = new Set<string>();
196+
for (const cerr of fullConfig?.configerrors ?? []) {
197+
errorSet.add(cerr.file);
198+
}
199+
return errorSet;
200+
});
192201
this.editorRef = React.createRef();
193202

194203
this.secretNamesAtom = atom<string[]>([]);

frontend/app/view/waveconfig/waveconfig.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import { Tooltip } from "@/app/element/tooltip";
5+
import { atoms } from "@/app/store/global";
56
import { globalStore } from "@/app/store/jotaiStore";
67
import { tryReinjectKey } from "@/app/store/keymodel";
78
import { CodeEditor } from "@/app/view/codeeditor/codeeditor";
@@ -21,6 +22,7 @@ const ConfigSidebar = memo(({ model }: ConfigSidebarProps) => {
2122
const [isMenuOpen, setIsMenuOpen] = useAtom(model.isMenuOpenAtom);
2223
const configFiles = model.getConfigFiles();
2324
const deprecatedConfigFiles = model.getDeprecatedConfigFiles();
25+
const configErrorFiles = useAtomValue(model.configErrorFilesAtom);
2426

2527
const handleFileSelect = (file: ConfigFile) => {
2628
model.loadFile(file);
@@ -46,7 +48,12 @@ const ConfigSidebar = memo(({ model }: ConfigSidebarProps) => {
4648
selectedFile?.path === file.path ? "bg-accentbg text-primary" : "hover:bg-secondary/50"
4749
}`}
4850
>
49-
<div className="whitespace-nowrap overflow-hidden text-ellipsis">{file.name}</div>
51+
<div className="flex items-center gap-1">
52+
<div className="whitespace-nowrap overflow-hidden text-ellipsis flex-1">{file.name}</div>
53+
{configErrorFiles.has(file.path) && (
54+
<i className="fa fa-solid fa-circle-exclamation text-error text-[14px] shrink-0" />
55+
)}
56+
</div>
5057
{file.description && (
5158
<div className="text-xs text-muted mt-0.5 whitespace-nowrap overflow-hidden text-ellipsis">
5259
{file.description}
@@ -75,6 +82,9 @@ const ConfigSidebar = memo(({ model }: ConfigSidebarProps) => {
7582
>
7683
deprecated
7784
</span>
85+
{configErrorFiles.has(file.path) && (
86+
<i className="fa fa-solid fa-circle-exclamation text-error text-[14px] ml-auto shrink-0" />
87+
)}
7888
</div>
7989
</div>
8090
))}
@@ -96,6 +106,8 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps<WaveConfigVi
96106
const [isMenuOpen, setIsMenuOpen] = useAtom(model.isMenuOpenAtom);
97107
const hasChanges = useAtomValue(model.hasEditedAtom);
98108
const [activeTab, setActiveTab] = useAtom(model.activeTabAtom);
109+
const fullConfig = useAtomValue(atoms.fullConfigAtom);
110+
const configErrors = fullConfig?.configerrors;
99111

100112
const handleContentChange = useCallback(
101113
(newContent: string) => {
@@ -148,7 +160,8 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps<WaveConfigVi
148160
const saveTooltip = `Save (${model.saveShortcut})`;
149161

150162
return (
151-
<div className="@container flex flex-row w-full h-full">
163+
<div className="@container flex flex-col w-full h-full">
164+
<div className="flex flex-row flex-1 min-h-0">
152165
{isMenuOpen && (
153166
<div className="absolute inset-0 bg-black/50 z-5 @w600:hidden" onClick={() => setIsMenuOpen(false)} />
154167
)}
@@ -284,6 +297,17 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps<WaveConfigVi
284297
</>
285298
)}
286299
</div>
300+
</div>
301+
{configErrors?.length > 0 && (
302+
<div className="bg-error text-primary px-4 py-1 max-h-12 overflow-y-auto border-t border-error/50 shrink-0">
303+
{configErrors.map((cerr, i) => (
304+
<div key={i} className="text-sm">
305+
<span className="font-semibold">Config Error: </span>
306+
{cerr.file}: {cerr.err}
307+
</div>
308+
))}
309+
</div>
310+
)}
287311
</div>
288312
);
289313
});

0 commit comments

Comments
 (0)