fix: cleanup of tag icon in action bar
This commit is contained in:
@@ -66,8 +66,8 @@ export const ActivityBar: React.FC = () => {
|
|||||||
// Check if settings view is active (either tab or sidebar)
|
// Check if settings view is active (either tab or sidebar)
|
||||||
const isSettingsActive = (activeView === 'settings' && sidebarVisible) || isSettingsTabActive;
|
const isSettingsActive = (activeView === 'settings' && sidebarVisible) || isSettingsTabActive;
|
||||||
|
|
||||||
// Check if tags tab is currently active
|
// Check if tags sidebar is active
|
||||||
const isTagsTabActive = tabs.some(t => t.type === 'tags' && t.id === activeTabId);
|
const isTagsActive = activeView === 'tags' && sidebarVisible;
|
||||||
|
|
||||||
// Check if chat sidebar is active (activeView === 'chat' and sidebar is visible)
|
// Check if chat sidebar is active (activeView === 'chat' and sidebar is visible)
|
||||||
const isChatActive = activeView === 'chat' && sidebarVisible;
|
const isChatActive = activeView === 'chat' && sidebarVisible;
|
||||||
@@ -108,8 +108,16 @@ export const ActivityBar: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleTagsClick = () => {
|
const handleTagsClick = () => {
|
||||||
// Open tags as a dedicated (non-transient) tab
|
// Toggle sidebar if tags is already active, otherwise switch to tags
|
||||||
openTab({ type: 'tags', id: 'tags', isTransient: false });
|
if (activeView === 'tags' && sidebarVisible) {
|
||||||
|
toggleSidebar();
|
||||||
|
} else {
|
||||||
|
openTab({ type: 'tags', id: 'tags', isTransient: false });
|
||||||
|
setActiveView('tags');
|
||||||
|
if (!sidebarVisible) {
|
||||||
|
toggleSidebar();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleImportClick = () => {
|
const handleImportClick = () => {
|
||||||
@@ -148,9 +156,9 @@ export const ActivityBar: React.FC = () => {
|
|||||||
<MediaIcon />
|
<MediaIcon />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`activity-bar-item ${isTagsTabActive ? 'active' : ''}`}
|
className={`activity-bar-item ${isTagsActive ? 'active' : ''}`}
|
||||||
onClick={handleTagsClick}
|
onClick={handleTagsClick}
|
||||||
title={t('activity.tags')}
|
title={`${t('activity.tags')} ${t('activity.toggleHint')}`}
|
||||||
>
|
>
|
||||||
<TagsIcon />
|
<TagsIcon />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1223,11 +1223,19 @@ import { scrollToTagsSection, TagsCategory } from '../TagsView';
|
|||||||
|
|
||||||
const TagsNav: React.FC = () => {
|
const TagsNav: React.FC = () => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { tabs, activeTabId, openTab } = useAppStore();
|
||||||
const [activeSection, setActiveSection] = useState<TagsCategory | null>(null);
|
const [activeSection, setActiveSection] = useState<TagsCategory | null>(null);
|
||||||
|
|
||||||
|
const isTagsTabActive = tabs.some(t => t.type === 'tags' && t.id === activeTabId);
|
||||||
|
|
||||||
const handleNavClick = (category: TagsCategory) => {
|
const handleNavClick = (category: TagsCategory) => {
|
||||||
|
if (!isTagsTabActive) {
|
||||||
|
openTab({ type: 'tags', id: 'tags', isTransient: false });
|
||||||
|
}
|
||||||
setActiveSection(category);
|
setActiveSection(category);
|
||||||
scrollToTagsSection(category);
|
setTimeout(() => {
|
||||||
|
scrollToTagsSection(category);
|
||||||
|
}, isTagsTabActive ? 0 : 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
98
tests/renderer/components/ActivityBar.test.tsx
Normal file
98
tests/renderer/components/ActivityBar.test.tsx
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { beforeEach, describe, expect, it } from 'vitest';
|
||||||
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
|
import { ActivityBar } from '../../../src/renderer/components/ActivityBar/ActivityBar';
|
||||||
|
import { I18nProvider } from '../../../src/renderer/i18n';
|
||||||
|
import { useAppStore } from '../../../src/renderer/store';
|
||||||
|
|
||||||
|
describe('ActivityBar tags behavior', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
useAppStore.setState({
|
||||||
|
activeView: 'posts',
|
||||||
|
sidebarVisible: true,
|
||||||
|
tabs: [],
|
||||||
|
activeTabId: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('opens tags tab and switches sidebar to tags view when clicking Tags', () => {
|
||||||
|
render(
|
||||||
|
<I18nProvider>
|
||||||
|
<ActivityBar />
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByTitle('Tags (click again to toggle sidebar)'));
|
||||||
|
|
||||||
|
const state = useAppStore.getState();
|
||||||
|
expect(state.activeView).toBe('tags');
|
||||||
|
expect(state.sidebarVisible).toBe(true);
|
||||||
|
expect(state.activeTabId).toBe('tags');
|
||||||
|
expect(state.tabs).toContainEqual({ type: 'tags', id: 'tags', isTransient: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toggles tags sidebar off when tags view is already active', () => {
|
||||||
|
useAppStore.setState({
|
||||||
|
activeView: 'tags',
|
||||||
|
sidebarVisible: true,
|
||||||
|
tabs: [{ type: 'tags', id: 'tags', isTransient: false }],
|
||||||
|
activeTabId: 'tags',
|
||||||
|
});
|
||||||
|
|
||||||
|
render(
|
||||||
|
<I18nProvider>
|
||||||
|
<ActivityBar />
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByTitle('Tags (click again to toggle sidebar)'));
|
||||||
|
|
||||||
|
expect(useAppStore.getState().sidebarVisible).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows tags sidebar when hidden and tags view is active', () => {
|
||||||
|
useAppStore.setState({
|
||||||
|
activeView: 'tags',
|
||||||
|
sidebarVisible: false,
|
||||||
|
tabs: [{ type: 'tags', id: 'tags', isTransient: false }],
|
||||||
|
activeTabId: 'tags',
|
||||||
|
});
|
||||||
|
|
||||||
|
render(
|
||||||
|
<I18nProvider>
|
||||||
|
<ActivityBar />
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByTitle('Tags (click again to toggle sidebar)'));
|
||||||
|
|
||||||
|
expect(useAppStore.getState().sidebarVisible).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not mark tags icon active when tags editor tab is open but another sidebar is active', () => {
|
||||||
|
useAppStore.setState({
|
||||||
|
activeView: 'posts',
|
||||||
|
sidebarVisible: true,
|
||||||
|
tabs: [{ type: 'tags', id: 'tags', isTransient: false }],
|
||||||
|
activeTabId: 'tags',
|
||||||
|
});
|
||||||
|
|
||||||
|
render(
|
||||||
|
<I18nProvider>
|
||||||
|
<ActivityBar />
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByTitle('Tags (click again to toggle sidebar)')).not.toHaveClass('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses the shared toggle hint in the tags activity button title', () => {
|
||||||
|
render(
|
||||||
|
<I18nProvider>
|
||||||
|
<ActivityBar />
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByTitle('Tags (click again to toggle sidebar)')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user