Skip to content

Conversation

@MrCoder
Copy link
Contributor

@MrCoder MrCoder commented Dec 28, 2025

Note

Major UX restructure with a new left sidebar and improved persistence/analytics.

  • Add LeftSidebar, LibraryPanel, EditorPanel, FolderRow; enable folder CRUD via services/folderService and item move between folders; redesign SavedItemPane and compact ItemTile
  • Refactor ContentWrap to support editor-in-sidebar, fixed horizontal splits, CodeMirror refresh on visibility, and move preview actions to PageTabs
  • Simplify header (MainHeader) and remove layout toggling; compute sizes using fixed horizontal assumptions
  • Migrate analytics from GA to mixpanel (analytics.js), deprecate GA-specific paths
  • Improve persistence and safety: db.js resilient localStorage parsing and Firestore persistence handling; safer SplitPane destroy/unmount; relative dates via getHumanDate
  • Styling: new .main-content-area, editor font size via --editor-font-size, updated iframe background; Tailwind cleanup
  • Bump @zenuml/core to ^3.43.2

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
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.

<Dialog.Portal>
<Dialog.Overlay className="bg-black/50 backdrop-blur-sm data-[state=open]:animate-overlayShow fixed inset-0" />
<Dialog.Content className="text-sm overflow-y-auto text-gray-500 data-[state=open]:animate-contentShow fixed top-[50%] left-[50%] max-h-[85vh] w-[90vw] overflow-hidden max-w-[650px] translate-x-[-50%] translate-y-[-50%] rounded-[6px] bg-black-400 p-[25px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none">
<Dialog.Title className="font-medium text-xl font-semibold">
Copy link

Choose a reason for hiding this comment

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

Broken debugging code would crash if ever invoked

The updateSetting function contains console.log(e)(e) which is invalid JavaScript. console.log() returns undefined, and the code then attempts to invoke undefined as a function with (e), which would throw a TypeError if this function were ever called. The function appears to be unused dead code (all handlers use props.onChange directly), but this is likely accidentally committed debugging code with a typo.

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.

Export buttons hidden when item has no pages

The Present, PNG export, and Copy PNG buttons were moved into the PageTabs component, but PageTabs is only rendered when currentItem.pages exists and has length greater than 0. This means items that don't use the pages feature will completely lose access to the fullscreen presentation, PNG export, and image copy functionality. These buttons were previously rendered unconditionally for all items.

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.

Direct mutation of props breaks React state model

The code directly mutates props with this.props.items[item.id] = updatedItem. In React/Preact, props are meant to be read-only and mutating them can cause state synchronization issues, missed re-renders, and bugs that are difficult to debug. The parent component's state won't reflect these changes properly, potentially causing the UI to show stale data or behave inconsistently.

Additional Locations (1)

Fix in Cursor Fix in Web

@MrCoder MrCoder merged commit 1923579 into master Dec 29, 2025
1 check passed
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.

3 participants