Spaces:
Sleeping
Sleeping
Download frontend/src/components/Header.tsx from Sid-WC121/visual-notebook: direct link, hf CLI and curl.
- Browser
- Download file 4.73 kB
-
https://huggingface.co/spaces/Sid-WC121/visual-notebook/resolve/main/frontend/src/components/Header.tsx
- Command line
-
hf download hf://spaces/Sid-WC121/visual-notebook/frontend/src/components/Header.tsx
-
curl -L -o Header.tsx https://huggingface.co/spaces/Sid-WC121/visual-notebook/resolve/main/frontend/src/components/Header.tsx
4.73 kB
| import React from 'react'; | |
| import { useSessionStore } from '../store/session'; | |
| import { useHistoryStore } from '../store/history'; | |
| import { useUIStore } from '../store/ui'; | |
| import { useHistory } from '../api/hooks'; | |
| export function Header() { | |
| const { isLoaded, tableName, rowCount } = useSessionStore(); | |
| const { canUndo, canRedo } = useHistoryStore(); | |
| const { toggleUploadDialog, toggleSidebar, showSidebar } = useUIStore(); | |
| const { undoAction, redoAction } = useHistory(); | |
| const handleUndo = async () => { | |
| const result = await undoAction(); | |
| if (result) useHistoryStore.getState().updateCurrent(result.state_id); | |
| }; | |
| const handleRedo = async () => { | |
| const result = await redoAction(); | |
| if (result) useHistoryStore.getState().updateCurrent(result.state_id); | |
| }; | |
| return ( | |
| <header className="bg-white border-b border-gray-200 sticky top-0 z-50"> | |
| <div className="w-full px-4 py-2.5 flex items-center justify-between"> | |
| {/* Left: sidebar toggle + logo + dataset info */} | |
| <div className="flex items-center gap-3 min-w-0"> | |
| {isLoaded && ( | |
| <button | |
| onClick={toggleSidebar} | |
| className="p-1.5 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors flex-shrink-0" | |
| title={showSidebar ? 'Hide sidebar' : 'Show sidebar'} | |
| > | |
| <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| {showSidebar ? ( | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 19l-7-7 7-7m8 14l-7-7 7-7" /> | |
| ) : ( | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" /> | |
| )} | |
| </svg> | |
| </button> | |
| )} | |
| <div className="w-8 h-8 bg-brand-600 rounded-lg flex items-center justify-center flex-shrink-0"> | |
| <svg className="w-5 h-5 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" /> | |
| </svg> | |
| </div> | |
| <h1 className="text-lg font-bold text-gray-900 flex-shrink-0">Visual Notebook</h1> | |
| {isLoaded && ( | |
| <span className="text-sm text-gray-500 ml-1 hidden sm:inline truncate"> | |
| <span className="text-gray-400 mx-1">·</span> | |
| {tableName} | |
| <span className="text-gray-400 mx-1">·</span> | |
| {rowCount.toLocaleString()} rows | |
| </span> | |
| )} | |
| </div> | |
| {/* Right: undo/redo + new file */} | |
| <div className="flex items-center gap-1.5 flex-shrink-0"> | |
| {isLoaded && ( | |
| <> | |
| <button | |
| onClick={handleUndo} | |
| disabled={!canUndo} | |
| className="p-1.5 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg disabled:opacity-30 disabled:cursor-not-allowed transition-colors" | |
| title="Undo" | |
| > | |
| <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a5 5 0 015 5v2M3 10l4-4M3 10l4 4" /> | |
| </svg> | |
| </button> | |
| <button | |
| onClick={handleRedo} | |
| disabled={!canRedo} | |
| className="p-1.5 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg disabled:opacity-30 disabled:cursor-not-allowed transition-colors" | |
| title="Redo" | |
| > | |
| <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 10H11a5 5 0 00-5 5v2M21 10l-4-4M21 10l-4 4" /> | |
| </svg> | |
| </button> | |
| <div className="w-px h-5 bg-gray-200 mx-1" /> | |
| <button onClick={toggleUploadDialog} className="btn-secondary text-xs py-1.5"> | |
| <span className="flex items-center gap-1.5"> | |
| <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" /> | |
| </svg> | |
| New File | |
| </span> | |
| </button> | |
| </> | |
| )} | |
| </div> | |
| </div> | |
| </header> | |
| ); | |
| } | |