Skip to content

Feature/project management ux#782

Merged
MrCoder merged 32 commits intomasterfrom
feature/project-management-ux
Dec 5, 2025
Merged

Feature/project management ux#782
MrCoder merged 32 commits intomasterfrom
feature/project-management-ux

Conversation

@MrCoder
Copy link
Contributor

@MrCoder MrCoder commented Dec 5, 2025

Note

Adds a left sidebar with a folder-based Library, fixes the app to a horizontal layout with sidebar editor support, and replaces Google Analytics with Mixpanel tracking.

  • App/Layout:
    • Fix layout to horizontal (layoutMode=1) and add sidebar-aware editor/preview sizing (editorInSidebar/hideEditor).
    • Refactor ContentWrap (split rendering, CodeMirror refresh on visibility) and SplitPane (safer destroy lifecycle).
    • UI tweaks in MainHeader, Footer, Tabs/Tab, and global styles (src/style.css, Tailwind base).
  • Library & Folders:
    • New left sidebar (components/LeftSidebar.jsx) with LibraryPanel for browsing saved items.
    • Folder management: create/rename/delete/move via folderService and new FolderRow; ItemTile supports compact mode and move action.
    • Updated SavedItemPane to support folders, search, and actions; keyboard shortcut to open library.
  • Editor/Preview:
    • CodeMirror font size via CSS var; relative time stamps via getHumanDate.
    • PageTabs adds Present/PNG/Copy actions; preview iframe uses srcdoc and new background grid.
  • Analytics & Data:
    • Replace Google Analytics with Mixpanel in analytics.js and event calls.
    • Harden Firestore persistence and localStorage parsing in db.js; survey service now uses window.db.getDb().
  • Dependencies:
    • Bump @zenuml/core to ^3.43.2 (lockfile updated).

Written by Cursor Bugbot for commit b5066b9. This will update automatically on new commits. Configure here.

- Fix JSON.parse() errors when reading legacy localStorage values
  - Added try-catch blocks in db.js local.get() to handle non-JSON strings
  - Gracefully falls back to raw string values for legacy data

- Fix Firebase persistence initialization error
  - Reorganized getDb() to call enablePersistence() on the db instance
  - Improved error handling to gracefully continue without persistence if needed
  - Updated surveyService.js to use centralized window.db.getDb()
  - Prevents 'persistence can no longer be enabled' errors

- Update @zenuml/core to v3.43.2
- Add folder organization for saved diagrams (tree view in My Library)
- Store folders in user profile document (no Firestore rule deployment needed)
- Add FolderRow component for expandable/collapsible folder display
- Add move-to-folder functionality on ItemTile with immediate UI update
- Add enhanced search with Cmd/Ctrl+K keyboard shortcut
- Auto-expand target folder after moving item for better UX

Bug fixes:
- Fix ItemTile props destructuring error (onMoveBtnClick)
- Fix SplitPane removeChild DOM error with try-catch
- Fix Firebase persistence error handling for SDK version mismatch
- Modernize layout with clean header, action buttons row, and search
- Add blue 'Add Folder' button with icon
- Style Export/Import buttons with gray background
- Add search icon inside search input field
- Redesign FolderRow with expand/collapse chevron and hover actions
- Add compact mode to ItemTile with clean card design
- Show action buttons on hover, hide timestamp
- Use consistent dark theme (gray-900 background)
- Improve spacing and visual hierarchy
- Reduce spacing: p-4 → p-3, mb-4 → mb-3, space-y-2 → space-y-1.5
- Folder rows: py-1.5, space-x-1.5 between elements
- Item tiles: p-2.5, space-x-2.5 for icon/title
- Add document icon to item tiles
- Use space-y-3 between folders, space-y-1.5 between items
- Match exact Tailwind classes from provided HTML mockup
- Support dark mode with dark: variants
- Default to dark theme (remove dark: variants)
- Sidebar: bg-gray-800, search/items: bg-gray-700
- Text colors: white, gray-200, gray-400
- Update getHumanDate() to show relative time (e.g. '3 hours ago', '2 days ago')
- Replace full date format with concise relative time
- Create LeftSidebar.jsx with Icon Bar for Library/Editor toggle
- Create LibraryPanel.jsx (embedded panel, refactored from SavedItemPane)
- Update app.jsx layout to include LeftSidebar with flex wrapper
- Add main-content-area CSS class for proper layout sizing
- Update FolderRow.jsx and ItemTile.jsx with compact mode styling
- Dark theme colors: bg-[#111722], bg-[#232f48], text-[#135bec]
- Remove SavedItemPane component rendering and import
- Remove isSavedItemPaneOpen state
- Update toggleSavedItemsPane to toggle left sidebar instead
- Update closeSavedItemsPane to close left sidebar
- Update closeAllOverlays to use isLibraryPanelOpen
- Create EditorPanel.jsx with ZenUML/CSS tabs for sidebar
- Update LeftSidebar to show EditorPanel when code_blocks icon clicked
- Add hideCodeSide prop to ContentWrap to hide editor when in sidebar
- Pass editor props through App.jsx to LeftSidebar
- Add CSS for sidebar editor panel layout
- Set hideCodeSide={true} to always hide the main area editor
- Editor is now only available in the left sidebar EditorPanel
- Add onJsEditorCreation and onCssEditorCreation callbacks
- Call setInitialCode after CodeMirror instances are created
- Load code from currentItem.pages or currentItem directly
- Reset initialCodeSet flag when currentItem.id changes
- Remove EditorPanel component usage (editor is now CSS-positioned)
- Use 'editorInSidebar' prop to control editor positioning via CSS
- Add CSS rules for #js-code-side.editor-in-sidebar to position editor in sidebar
- Library panel only shows when activeLeftPanel === 'library'
- Preserves full syntax highlighting and all editor features
- Add hideEditor prop to ContentWrap to hide editor when library is active
- Refresh CodeMirror when switching between editor/library modes
- Library mode: shows Library panel + Preview only
- Editor mode: shows Editor in sidebar + Preview
- Refactor ContentWrap to use renderEditor() and renderPreview() methods
- Keep SplitPane for both modes to preserve CodeMirror instance
- Use narrower editor (25%) in sidebar mode, wider preview (75%)
- Remove DOM manipulation approach in favor of CSS-based sizing
- Both library and editor modes now work without overlap
- Removed DOM container that was part of the old DOM manipulation approach
- Editor is now handled via SplitPane sizing instead
- Removed the three layout buttons (preview on right/bottom/left)
- Simplified bottom toolbar to only show Present, PNG, and Copy PNG buttons
- Remove toggleLayout and layoutBtnClickHandler methods from app.jsx
- Remove currentLayoutMode state and prop passing
- Simplify getCodePaneSizes and getMainPaneSizes to use fixed horizontal layout
- Remove layout mode checks from ContentWrap (always use horizontal)
- Remove layout rotation classes from MainHeader
- Remove unused layoutBtnClickhandler from Footer
- Layout is now fixed to horizontal (editor on left, preview on right)
- Fetch items with shouldSaveGlobally=true when user logs in
- Use setState instead of direct state mutation in fetchItems
- Items now load immediately when user logs in, no need for second click
- Default to code editor mode on page load (activeLeftPanel: 'editor')
- Set isLibraryPanelOpen to false by default
- Fix: clicking active button no longer switches to other panel
- Code button click when active → does nothing
- Library button click when active → does nothing
- Add isEditorPanelOpen state to track editor panel visibility
- Code button click when open → closes editor, shows just preview
- Code button click when closed → opens editor
- Library button click when open → closes library, shows just preview
- Library button click when closed → opens library
- Both panels can be toggled independently
- Remove Toggle editor pane button from MainHeader
- Remove isEditorCollapsed state from app.jsx
- Remove toggleEditorCollapse method from app.jsx
- Remove isEditorCollapsed prop from ContentWrap
- Editor visibility is now controlled by left sidebar buttons only
- Call openSavedItemsPane() when switching to library panel via onSwitchPanel
- Call openSavedItemsPane() when toggling library panel open via onToggleLibraryPanel
- Change populateItemsInSavedPane to always open pane (pass true) instead of toggling
- Add await to fetchItems(true) call on user login for proper async handling
- Add onToggleFullscreen, onExportPng, onCopyImage props to PageTabs
- Move Present, PNG, Copy PNG buttons from bottom bar to page tabs
- Remove bottom action bar from ContentWrap
- Update button styling to match dark theme of page tabs
Library is now accessible via the left sidebar folder_open icon
- Move page tabs bar to bottom of preview area
- Change active page tab color from blue to lighter gray
- Remove Indentation, Preprocessors, Key bindings settings from modal
- Remove unused checkbox settings (auto-close tags, refresh on resize, etc.)
- Remove 'Keyboard Shortcuts' title from settings modal
- Fix font size setting by using CSS custom property
- Move Settings, Cheatsheet, Language Guide to left sidebar
- Remove dropdown menu from header, keep only logo
- Clean up unused imports and functions
- Add Shortcuts button to left sidebar (keyboard icon)
- Remove Shortcuts button from Tabs component
- Center tab text horizontally with justify-center
- Fix font size CSS custom property for editor
- Remove deprecated Google Analytics (UA-1211588-20) code
- Update trackEvent() to send events via Mixpanel /track endpoint
- Update trackPageView() to use Mixpanel
- Make trackGaSetField() a no-op (GA-specific)

All existing trackEvent calls now automatically go to Mixpanel.
- Remove !important font-size override from tailwind.css that was blocking Font Size setting
- Add dark dot grid background to diagram preview (#demo-frame)
  - background-color: #1f2937 (gray-800)
  - dot pattern: #4b5563 (gray-600) at 20px intervals
- Change buttons, label, and input box from font-semibold to font-normal
- Update text color from text-gray-400 to text-[#F2F2F2]
- Remove duplicate color styles from style.css (now using Tailwind classes)
- Add refresh button in LibraryPanel action buttons (next to Export/Import)
- Pass onReloadLibrary prop through LeftSidebar to LibraryPanel
- Clicking reload calls fetchItems(true) to force refresh from Firestore
@MrCoder MrCoder merged commit 193a0d1 into master Dec 5, 2025
3 checks passed
@MrCoder MrCoder deleted the feature/project-management-ux branch December 5, 2025 04:06
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bug: Unused function contains code that throws TypeError

The updateSetting function contains console.log(e)(e) which attempts to invoke the return value of console.log(e) (which is undefined) as a function. While currently unused since the component uses props.onChange instead, this code would throw a TypeError if ever invoked. This appears to be accidentally committed debugging code.

src/components/SettingsModal.jsx#L40-L43

export default function SettingsModal(props) {
const updateSetting = (e) => {
console.log(e)(e);
};

Fix in Cursor Fix in Web


onExportPng={this.exportPngClickHandler.bind(this)}
onCopyImage={this.copyImageClickHandler.bind(this)}
/>
)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Export buttons hidden when pages array is empty

The PageTabs component containing export functionality (PNG export, Copy PNG, and Present/Fullscreen buttons) is only rendered when pages.length > 0. Previously these buttons were rendered unconditionally in the preview section. Users without pages will no longer have access to export their diagrams as PNG, copy images to clipboard, or enter fullscreen mode.

Fix in Cursor Fix in Web

}

if (this.props.items && this.props.items[item.id]) {
this.props.items[item.id] = updatedItem;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Direct mutation of props.items in folder operations

When moving items to folders, the code directly mutates this.props.items[item.id]. Mutating props is an anti-pattern in React/Preact that bypasses the component lifecycle and can cause inconsistent state between parent and child components. The parent component won't be notified of this change and won't re-render appropriately.

Additional Locations (1)

Fix in Cursor Fix in Web

}

return d.promise;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Items not updated when folder is deleted

When deleting a folder, the confirmation dialog states "Items inside will be moved to Unfiled" but the deleteFolder function only removes the folder from the folders array without updating the folderId property of items in that folder to null. Items will appear unfiled due to rendering logic filtering, but their data retains the deleted folder's ID. This creates data inconsistency that could cause issues with data export/import or if folder IDs are ever reused.

Additional Locations (1)

Fix in Cursor Fix in Web

@MrCoder MrCoder restored the feature/project-management-ux branch December 28, 2025 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant