feat(FN-1442): replace emoji scope icons with theme-aware Lucide icons
- Replace emoji icons (🌐, 📁) with Lucide Globe and Folder icons in Settings sidebar scope indicators - Icons now automatically adapt to light/dark theme colors for better visual consistency - Update SettingsModal tests to validate Lucide icon rendering - Add mobile-specific tests for settings scope indicators
This commit is contained in:
@@ -579,12 +579,12 @@ export function SettingsModal({
|
||||
setPresetDraft(null);
|
||||
};
|
||||
|
||||
/** Render a scope indicator banner for the current section */
|
||||
/** Render a scope indicator banner for the current section with theme-aware Lucide icons */
|
||||
const renderScopeBanner = () => {
|
||||
if (activeSectionScope === "global") {
|
||||
return (
|
||||
<div className="settings-scope-banner settings-scope-global">
|
||||
<span>🌐</span>
|
||||
<span className="settings-scope-icon"><Globe size={14} /></span>
|
||||
<span>These settings are shared across all your Fusion projects.</span>
|
||||
</div>
|
||||
);
|
||||
@@ -592,7 +592,7 @@ export function SettingsModal({
|
||||
if (activeSectionScope === "project") {
|
||||
return (
|
||||
<div className="settings-scope-banner settings-scope-project">
|
||||
<span>📁</span>
|
||||
<span className="settings-scope-icon"><Folder size={14} /></span>
|
||||
<span>These settings only affect this project.</span>
|
||||
</div>
|
||||
);
|
||||
@@ -600,7 +600,8 @@ export function SettingsModal({
|
||||
if (activeSectionScope === "mixed") {
|
||||
return (
|
||||
<div className="settings-scope-banner settings-scope-mixed">
|
||||
<span>🌐📁</span>
|
||||
<span className="settings-scope-icon"><Globe size={14} /></span>
|
||||
<span className="settings-scope-icon"><Folder size={14} /></span>
|
||||
<span>
|
||||
This section contains both global settings (default & fallback models) and project
|
||||
settings (planning, validator, presets, and AI summarization).
|
||||
|
||||
@@ -2040,7 +2040,7 @@ describe("SettingsModal", () => {
|
||||
expect(payload.maxStuckKills).toBeUndefined();
|
||||
});
|
||||
|
||||
it("scope banners render for global and project sections", async () => {
|
||||
it("scope banners render for global and project sections with theme-aware icons", async () => {
|
||||
const { container } = render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
@@ -2048,22 +2048,34 @@ describe("SettingsModal", () => {
|
||||
expect(container.querySelector(".settings-scope-project")).toBeNull();
|
||||
expect(container.querySelector(".settings-scope-global")).toBeNull();
|
||||
|
||||
// Switch to Appearance → should show global banner
|
||||
// Switch to Appearance → should show global banner with Globe icon (SVG, not emoji)
|
||||
fireEvent.click(screen.getAllByText("Appearance")[0]);
|
||||
expect(container.querySelector(".settings-scope-global")).toBeTruthy();
|
||||
expect(container.querySelector(".settings-scope-global")?.textContent).toContain("Fusion");
|
||||
const globalBanner = container.querySelector(".settings-scope-global");
|
||||
expect(globalBanner).toBeTruthy();
|
||||
expect(globalBanner?.textContent).toContain("Fusion");
|
||||
expect(container.querySelector(".settings-scope-project")).toBeNull();
|
||||
// Verify banner uses SVG icon, not emoji
|
||||
const globalIcon = globalBanner!.querySelector(".settings-scope-icon svg");
|
||||
expect(globalIcon).toBeTruthy();
|
||||
|
||||
// Switch to General → should show project banner
|
||||
// Switch to General → should show project banner with Folder icon (SVG, not emoji)
|
||||
fireEvent.click(screen.getAllByText("General")[0]);
|
||||
expect(container.querySelector(".settings-scope-project")).toBeTruthy();
|
||||
const projectBanner = container.querySelector(".settings-scope-project");
|
||||
expect(projectBanner).toBeTruthy();
|
||||
expect(container.querySelector(".settings-scope-global")).toBeNull();
|
||||
// Verify banner uses SVG icon, not emoji
|
||||
const projectIcon = projectBanner!.querySelector(".settings-scope-icon svg");
|
||||
expect(projectIcon).toBeTruthy();
|
||||
|
||||
// Switch to Models → should show mixed scope banner (contains both global and project settings)
|
||||
// Switch to Models → should show mixed scope banner with both icons (SVG, not emoji)
|
||||
fireEvent.click(screen.getAllByText("Models")[0]);
|
||||
expect(container.querySelector(".settings-scope-mixed")).toBeTruthy();
|
||||
expect(container.querySelector(".settings-scope-mixed")?.textContent).toContain("global");
|
||||
expect(container.querySelector(".settings-scope-mixed")?.textContent).toContain("project");
|
||||
const mixedBanner = container.querySelector(".settings-scope-mixed");
|
||||
expect(mixedBanner).toBeTruthy();
|
||||
expect(mixedBanner?.textContent).toContain("global");
|
||||
expect(mixedBanner?.textContent).toContain("project");
|
||||
// Verify mixed banner uses both icons as SVG elements, not emoji
|
||||
const mixedIcons = mixedBanner!.querySelectorAll(".settings-scope-icon svg");
|
||||
expect(mixedIcons.length).toBe(2);
|
||||
});
|
||||
|
||||
// --- Settings save error handling tests ---
|
||||
|
||||
@@ -108,9 +108,21 @@ describe("SettingsModal mobile adaptations", () => {
|
||||
// Authentication is first with no scope banner by default - click General to see project scope
|
||||
expect(container.querySelectorAll(".settings-scope-icon").length).toBeGreaterThan(0);
|
||||
await user.click(getAllByText("General")[0]);
|
||||
|
||||
// Verify project scope banner contains icon elements (SVG from Lucide, not emoji)
|
||||
const projectBanner = container.querySelector(".settings-scope-project");
|
||||
expect(projectBanner).toBeTruthy();
|
||||
const projectBannerIcon = projectBanner!.querySelector(".settings-scope-icon svg");
|
||||
expect(projectBannerIcon).toBeTruthy();
|
||||
expect(getByText("These settings only affect this project.")).toBeTruthy();
|
||||
|
||||
await user.click(getByText("Appearance"));
|
||||
|
||||
// Verify global scope banner contains icon elements (SVG from Lucide, not emoji)
|
||||
const globalBanner = container.querySelector(".settings-scope-global");
|
||||
expect(globalBanner).toBeTruthy();
|
||||
const globalBannerIcon = globalBanner!.querySelector(".settings-scope-icon svg");
|
||||
expect(globalBannerIcon).toBeTruthy();
|
||||
expect(getByText("These settings are shared across all your Fusion projects.")).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user