Skip to content

Commit 2d8532d

Browse files
committed
fix: sync space name on switch and add import/export to Settings tab
- Fix stale space name in sidebar when creating or switching spaces by syncing editSpaceNameValue with the spaceName prop via useEffect - Add import/export ZIP buttons to the Settings tab for discoverability (previously only on the Spaces tab) - Add tests for both fixes https://claude.ai/code/session_01WsFd9hPNmHcP9kJCj7fZHM
1 parent 3a07c6f commit 2d8532d

4 files changed

Lines changed: 68 additions & 0 deletions

File tree

packages/ui/src/components/settings/SettingsModal.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,28 @@ describe('SettingsModal', () => {
174174
expect(onClose).toHaveBeenCalled();
175175
});
176176

177+
it('shows export/import space buttons on settings tab when handlers provided', () => {
178+
const onExportSpace = vi.fn();
179+
const onImportSpace = vi.fn();
180+
const onClose = vi.fn();
181+
render(
182+
<SettingsModal
183+
{...defaultProps}
184+
initialTab="settings"
185+
onExportSpace={onExportSpace}
186+
onImportSpace={onImportSpace}
187+
onClose={onClose}
188+
/>,
189+
);
190+
const exportBtn = screen.getByTestId('settings-export-space-btn');
191+
const importBtn = screen.getByTestId('settings-import-space-btn');
192+
expect(exportBtn).toBeDefined();
193+
expect(importBtn).toBeDefined();
194+
exportBtn.click();
195+
expect(onExportSpace).toHaveBeenCalled();
196+
expect(onClose).toHaveBeenCalled();
197+
});
198+
177199
it('shows clear all data button in spaces tab', () => {
178200
render(<SettingsModal {...defaultProps} initialTab="spaces" />);
179201
expect(screen.getByTestId('settings-panel-spaces')).toBeDefined();

packages/ui/src/components/settings/SettingsModal.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,39 @@ export function SettingsModal({
283283
</button>
284284
</label>
285285

286+
{(onExportSpace || onImportSpace) && (
287+
<>
288+
<div className="cept-settings-section-divider" />
289+
<h3 className="cept-settings-section-title">Import / Export</h3>
290+
<div className="cept-settings-actions">
291+
{onExportSpace && (
292+
<button
293+
className="cept-settings-action-btn"
294+
onClick={() => { onExportSpace(); onClose(); }}
295+
data-testid="settings-export-space-btn"
296+
>
297+
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
298+
<path d="M8 2v8M5 5l3-3 3 3M3 11v2h10v-2" />
299+
</svg>
300+
Export space as ZIP
301+
</button>
302+
)}
303+
{onImportSpace && (
304+
<button
305+
className="cept-settings-action-btn"
306+
onClick={() => { onImportSpace(); onClose(); }}
307+
data-testid="settings-import-space-btn"
308+
>
309+
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
310+
<path d="M8 10V2M5 7l3 3 3-3M3 11v2h10v-2" />
311+
</svg>
312+
Import space from ZIP
313+
</button>
314+
)}
315+
</div>
316+
</>
317+
)}
318+
286319
<div className="cept-settings-section-divider" />
287320
<button
288321
className="cept-settings-danger-btn"

packages/ui/src/components/sidebar/Sidebar.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ describe('Sidebar', () => {
212212
expect(screen.getByText('My Workspace')).toBeDefined();
213213
});
214214

215+
it('updates displayed space name when spaceName prop changes', () => {
216+
const { rerender } = render(<Sidebar pages={mockPages} spaceName="Demo Space" />);
217+
expect(screen.getByText('Demo Space')).toBeDefined();
218+
rerender(<Sidebar pages={mockPages} spaceName="New Project" />);
219+
expect(screen.getByText('New Project')).toBeDefined();
220+
expect(screen.queryByText('Demo Space')).toBeNull();
221+
});
222+
215223
it('renders back button when onBackToSpace is provided', () => {
216224
const onBackToSpace = vi.fn();
217225
render(<Sidebar pages={mockPages} onBackToSpace={onBackToSpace} />);

packages/ui/src/components/sidebar/Sidebar.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ export function Sidebar({
8080
position: { x: number; y: number };
8181
} | null>(null);
8282

83+
// Sync editSpaceNameValue when spaceName prop changes (e.g., after creating or switching spaces)
84+
useEffect(() => {
85+
setEditSpaceNameValue(spaceName ?? 'Space');
86+
}, [spaceName]);
87+
8388
const handleContextMenu = useCallback(
8489
(id: string, title: string, position: { x: number; y: number }) => {
8590
setContextMenu({ pageId: id, pageTitle: title, position });

0 commit comments

Comments
 (0)