Commit 740a572
fix(measure): rename config DEM field from 'dem' to 'url' (#980)
* Sync toggleTimeUI DOM state to Zustand store
toggleTimeUI() now calls setTimeUIActive() and setTimeUIExpanded()
so BottomFloatingBar visibility and BottomElementPositioner offsets
reflect actual TimeUI state.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Restore #toggleTimeUI element in Coordinates markup
The element was accidentally dropped during the folder restructure move.
TimeUI.js and DrawTool.js check $('#toggleTimeUI').hasClass('active')
to gate histogram rendering and time-filter toggle visibility.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix #toggleTimeUI: restore click handler, tippy, active class; remove redundant jQuery positioning
Restored pieces lost during folder restructure:
- Click handler in init() and off handler in remove()
- Tippy tooltip for the time toggle button
- display:none when time is not enabled
- $('#toggleTimeUI').toggleClass('active') so TimeUI.js can check it
- $('#CoordinatesDiv > #toggleTimeUI').remove() on mobile
Removed jQuery CSS positioning from toggleTimeUI() since
BottomElementPositioner now reactively handles all bottom-anchored
element offsets via the Zustand store.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix CurtainTool.destroy() using undefined ReactDOM.unmountComponentAtNode
Use the stored _reactRoot.unmount() instead, matching the React 18
createRoot pattern already used in make().
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix tooltips, scale indicator position, modal blur, help close button
Tooltips:
- Reduce Base UI Tooltip delay from 600ms (default) to 200ms
- Restyle tooltip popup to match tippy blue theme (var(--color-c2))
- Add Tooltip wrappers to TopBar panel toggles (Viewer/Map/Globe)
- Wrap Toggle with forwardRef so Tooltip render prop can attach ref
- Remove title attrs that conflicted with custom tooltips
Scale indicator:
- Remove scalefactor-specific positioning from BottomElementPositioner
(it moves naturally with .leaflet-bottom.leaflet-left container)
- Position scalefactor to the left of compass at same bottom level
Modal blur:
- Call _applyBlur() immediately when marking modal as closing
so blur clears during fade-out instead of persisting 500ms
Help modal:
- Add close (X) button in title bar matching other modal patterns
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Remove dead CSS: delete tools.css, clean ~600 lines from mmgisUI.css and mmgis.css
- Delete tools.css entirely (both selectors #CurtainToolList and
.searchToolSelect are unreferenced anywhere in the codebase)
- Remove from mmgisUI.css: .mmgisRadioBar3/4/Vertical (140 lines),
.mmgispureselect (104 lines), blink/condemned_blink_effect (38 lines),
.slidecontainer/.slider (41 lines), .ar_slider (91 lines),
.verticalSlider (91 lines), .mmgisMultirange_elev (19 lines),
.ui-corner-all/bottom/right/br (9 lines)
- Remove from mmgis.css: #nodeenv, empty #topBar{}, #topBarInfo,
#topBarHelp, #topBarFullscreen, #toggleUI, #logoGoBack
- Keep #topBarLink (used in BottomBarReact.jsx), #webgl-error-message
(used by vendored THREE.js)
- All selectors verified with repo-wide grep before removal
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* UI fixes: tooltips, splitter hover, mobile toolbar, color schemes
- Replace Base UI Tooltip with simple React portal tooltip (200ms delay,
tippy-matching style) — fixes missing tooltips for toolbar/topbar/bottom buttons
- Add cursor + hover highlight to vertical splitters (was missing because
module CSS didn't inherit global .splitterV styles)
- Add hover highlight to tool panel drag handle
- Remove mdi-drag-vertical icon from tool panel drag
- Add mobile toolbar horizontal layout via @media query overrides
- Add 4 new color schemes: High Contrast (a11y), Dark Mars, Dark Midnight,
Light Warm (total: 10 themes)
- Previous fixes also included in working tree:
- timeUI border moved to toolsWrapper border-bottom (conditional)
- #toggleTimeUI button removed entirely
- CoordinatesDiv: vertical centering, unified background, 12px right offset
- barBottom padding-bottom: 8px
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix assignment operator used instead of comparison in TimeControl.fina()
Pre-existing bug: `TimeControl.enabled = true` was assigning instead of
comparing. Changed to `TimeControl.enabled === true`.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Restructure Configure page UI tab: add all themes, Custom mode, enableWhenField
- Added all 10 theme presets to dropdown (was missing Dark Mars, Dark Midnight,
Light Warm, High Contrast)
- Added 'Custom' option: skips preset theme, uses only color picker values
- Moved Theming section directly under Rebranding
- Nested 'Custom Color Options' under Theming with subdescription
- Added enableWhenField support to Maker.js: disables color pickers unless
theme is set to Custom
- Renamed color options with clearer names and improved descriptions:
Primary → Surface Color, Secondary → Deep Background Color,
Tertiary → Text Color, Body → Page Body Color, Highlight → Feature Highlight
- Stylize.js: skip setTheme() when theme is 'Custom'
- Rebuilt configure page
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Revert tooltips to tippy.js, fix dropdown menus, redesign About modal
1. Tooltip: Replaced custom React portal tooltip with tippy.js wrapper.
Uses the existing tippy.js dependency and 'blue' theme for consistency.
2. Dropdown: Replaced Base UI Menu with native portal dropdown.
Base UI's nested Menu.Trigger + BaseButton composition was swallowing
click events, breaking userAvatar and menuBtn menus. New implementation
uses simple state + createPortal with proper outside-click dismissal.
3. About modal: Professional redesign with centered MMGIS ASCII art header,
proper GitHub SVG logo link, clean metadata section, centered link
buttons, attributions section, and NASA-AMMOS footer.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Restore .mmgisHelpButton base styles lost during Help.css module migration
The global .mmgisHelpButton styles (yellow color, compact 18x18px sizing,
0.7 opacity) were removed when Help.css was converted to Help.module.css.
Since Help.getComponent() emits raw HTML strings for jQuery-rendered tool
headers, it cannot use CSS Module scoped classes. Restored the base styles
in mmgis.css alongside the related .mmgisToolHelpBtn definition.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix session logout regression, About modal refinements, High Contrast theme, Stylize.js, Default Tool config
- Login: skip session.regenerate() for token-based re-auth (useToken:true)
so reloading the main page no longer invalidates the configure page session
- About modal: replace ASCII art with mmgis.png logo, rename Attributions to
Map Layer Attributions, remove footer logo, link NASA-AMMOS to ammos.nasa.gov
- High Contrast theme: change accent from #ffff00 to #ffd700 (gold) for better
contrast ratios against dark backgrounds
- Stylize.js: color overrides only apply when theme is Custom or unset,
preventing preset themes from being clobbered by stale config values
- Restore Default Tool config section in tab-ui-config.json (accidentally
removed during Theming section reorganization)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Restore defaulttooldropdown case handler in Maker.js
The case was accidentally removed during the Configure page UI tab
restructure (d7f96c50). Without it, the Default Tool dropdown in the
Configure page rendered as nothing despite the config referencing it.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* High Contrast tooltip text, panel toggle styling, scale position swap
- High Contrast theme: tooltips now use black text on yellow background
via --color-c2-text variable (white for all other themes)
- About modal links use var(--color-f) for consistent theme text color
- Panel toggle buttons: 11px uppercase with 600 weight for better
visibility
- Mapping scale button moved to bottom-right of compass (was top-left)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Reposition Viewer and Globe panel buttons to top-right
- Viewer: dropdown selector at top-right edge, OSD buttons stacked
vertically below it; settings panel opens to the left
- Globe: home, exaggerate, observe, walk, link controls moved from
TopLeft to TopRight corner via addControl 4th arg
- Style consistency: OSD buttons and LithoSphere controls now match
Leaflet zoom controls (var(--color-a) bg, var(--color-f) text,
var(--color-mmgis) hover, 30px size, 3px border-radius)
- Viewer settings sliders use var(--color-a3) instead of hardcoded
#444444
- Az/el indicator stays at bottom center (exception per design)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Consistent modal theming + session security fix
Modal theming:
- All modals now share consistent styling: backdrop-filter blur, semi-transparent
background via --color-a-rgb, 10px border-radius, header divider line, box-shadow
- Updated: loginModal, Help, ConfirmationModal, Settings, Hotkeys, About modals
- Tool panel backgrounds changed from opaque var(--color-k) to transparent so the
ToolPanel's existing backdrop-filter effect shows through
- Legend tool header updated to match consistent 44px height with divider
- applyTheme.js now auto-derives --color-a-rgb from theme's --color-a hex value
- Modal service wrapper gets backdrop-filter: blur(12px)
Session security (Devin Review fix):
- Token re-auth now calls req.session.regenerate() with data preservation to
prevent session fixation while maintaining multi-tab compatibility
- Token is rotated via crypto.randomBytes on every re-auth (was being reused)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* UI fixes: viewer settings, button sizing, menu contrast, coords, login header
1. Viewer OSD settings moved to top of button stack, panel opens downward
2. Overlay buttons consistent 30x30px (OSD line-height fix, home button)
3. Menu/icon contrast improved: Dropdown items and IconButtons use --color-a5
(was --color-a3) with --color-f on hover for better dark theme legibility
4. CoordinatesDiv fixed to 30px height, pickLngLat button centered
5. Login modal now has a header bar with 'Log In' title and close X button;
title toggles to 'Sign Up' when switching modes
Also reverts session regeneration for token re-auth (Devin Review feedback):
token-based re-auth now refreshes session data in-place without regeneration
or token rotation, preserving multi-tab compatibility.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* UI polish: nav popover, sep tools, compass, zoom controls, status indicator, toast
1. Description nav popover: added z-index:9000 so menu appears above map panels
2. Separated tools: default color changed from accent to --color-f; fixed CSS
selector from .toolButtonSep to .toolSep to match actual class names
3. Compass + mapping scale shifted left by 30px for better positioning
4. Map zoom/home controls: use --color-f instead of accent --color-c to reduce
visual prominence; hover still highlights with accent color
5. Status indicators (reload/ws disconnect/layer update) moved from Leaflet
control to TopBar with soft pulsing fade animation and tooltip on hover
6. WebSocket retry toast: rounded corners, glass background with backdrop-filter,
border-left accent for failure state instead of solid red background
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix 14 tool UI issues: headers, backgrounds, layout, functional bugs
Header alignment:
- LayersTool: align-items center on #filterLayers, gap between right icons
- InfoTool: align-items center on #infoToolHeader, 44px height
- ViewshedTool: align-items center, restructured header with left/right divs
- IsochroneTool: restructured flat header into nested mmgisToolHeader pattern
- ShadeTool: align-items center on #vstHeader children
Icon spacing:
- LayersTool: increased right margin to 28px + gap 2px
- ViewshedTool: #vstNew padding-right 30px (clear of close button)
- IsochroneTool: #iscNew padding-right 30px
Missing components:
- SitesTool: added Help import + help icon via mmgisToolHeader pattern
- AnimationTool: added full mmgisToolHeader with title and help icon
Background fixes:
- InfoTool: changed toolsContainer background from transparent to var(--color-a)
- DrawTool: changed toolsContainer background from transparent to var(--color-a)
Layout fixes:
- DrawTool: #drawToolContents top 81px, height calc(100%-81px), #drawToolNav margin-right 0
- MeasureTool: removed padding-left:0 override from mmgisToolHeader child selector
Functional fixes:
- InfoTool: updated jQuery selectors from #InfoTool to #toolButtonInfo (React toolbar IDs changed)
- CurtainTool: deferred OpenSeadragon init with requestAnimationFrame (React 18 async render)
- CurtainTool: curtainToolBar justify-content flex-end (icons at bottom)
Security:
- TopBar StatusIndicator: escape HTML in layer names to prevent XSS via addLayerQueue
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix mapToolBar pointer events, login padding, default tool, About modal order
1. mapToolBar: set pointer-events:none on both #mapToolBar and direct children
so clicks pass through to the map; leaf elements still get auto via
.childpointerevents rule
2. #loginModalBody: padding changed to 40px 0px 0px
3. Default tool: deferred click to requestAnimationFrame so React toolbar
has rendered before getElementById runs
4. About modal: moved mainInfoModalCustom to right below mainInfoModalHero
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix tool headers to 40px, ViewshedTool subheader, AnimationTool header, InfoTool close btn, statusIndicator position
1. All tool panel headers: changed from 44px to exactly 40px height
- Global .mmgisToolHeader and .mmgisToolTitle in mmgis.css
- InfoTool.css, ViewshedTool.css, IsochroneTool.css, ShadeTool.css
2. LayersTool #filterLayers: height 40px, .right > div height unset,
.right margin-right 30px, .right > div margin 0px 3px
3. ViewshedTool: restructured header — title+help in mmgisToolHeader row,
vstToggleAll (left) and vstNew (right) on a new #vstSubHeader row below
4. AnimationTool: removed old #animationToolHeader CSS (padding 15px 20px,
white background, 18px font), now uses standard mmgisToolHeader class.
Fixed color from var(--color-a) (background) to var(--color-f) (text)
5. InfoTool close X: re-inject close button after use() rebuilds content
via TC_.injectCloseButton() (toolsContainer.empty() was removing it)
6. StatusIndicator: moved to left of topBarTitle in JSX render order.
Added align-items:center to #topBarMain for vertical alignment.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Remove title attr from StatusIndicator (conflicts with tippy tooltip)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix TimeUI dropdown z-index above tool panel, reposition toasts to top-center
1. TimeUI dropdowns: added z-index 10000 to all dropy content ul elements
so they render above the vertical tool panel (z-index 1400). Also set
timeUIDock to position:relative with z-index 10000 and overflow:visible.
2. Toast notifications: repositioned #toast-container from bottom-right to
top-center just below the topbar (top: 44px, centered with transform).
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix StatusIndicator spacing, CurtainTool close btn, header title font consistency
1. StatusIndicator: use display:none/flex instead of opacity:0/1 so it
takes no space when there's no active status indicator.
2. CurtainTool: added close X button at top of curtainToolBar (matching
MeasureTool pattern) with flex spacer pushing other buttons to bottom.
3. Header title font consistency: InfoTool, ShadeTool, CurtainTool titles
now match mmgisToolTitle standard (font-weight:600, padding-left:10px,
height:40px for CurtainTool which was 34px).
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Legend empty state, scalefactor position, sep-tool-header unbold
1. Legend: show 'No active layers with legends' when no legend items
are present. Also fixed container height calc(100% - 40px).
2. Mapping Scale (.leaflet-control-scalefactor): shifted 10px right
(left 26→36px) and 1px down (bottom 30→29px).
3. sep-tool-header span: font-weight changed from 600 to 400.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Guard Legend empty state message to only show when panel is active
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix TimeUI dropdown covered by toolPanel: remove splitscreens stacking context
#splitscreens had z-index:1 which created a stacking context, confining
its children (including bottomFloatingBar at z-index:1500) to that context.
Since ToolPanel (z-index:1400) was a sibling outside splitscreens, it
painted above all splitscreens children regardless of their internal
z-index values.
Fix: change #splitscreens z-index from 1 to auto so it no longer creates
a stacking context. Now bottomFloatingBar (1500) participates in the
same stacking context as ToolPanel (1400), and 1500 > 1400 means the
TimeUI dropdown correctly paints above the tool panel.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Migrate ~69 CursorInfo toast-like calls to proper Toast component
- Replace CursorInfo.update() toast-like calls with Toast.info/success/warning/error
- Preserve message colors: blue→info, green→success, yellow→warning, red→error
- Keep 12 legitimate cursor-following CursorInfo calls unchanged
- Files migrated: DrawTool.js, DrawTool_Files.js, DrawTool_FileModal.js,
DrawTool_Templater.js, DrawTool_SetOperations.js, DrawTool_Drawing.js,
DrawTool_Editing.js, DrawTool_Shapes.js, LayersTool.js, ShadeTool.js,
chemistrychart.js
- Fix Devin Review: Change misleading 'Bad token' to 'Login failed' in users.js
- Normalize line endings (CRLF→LF) in affected files
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix Toast.js missing from git, CoordinatesDiv z-index, Legend duplicate ID, topBar padding
- Add Toast.js to version control (was untracked, causing webpack module error)
- Bump CoordinatesDiv z-index from 20 to 1001 (was hidden behind splitscreens
children after z-index:auto change)
- Fix Legend duplicate ID: separated tool icon was #LegendTool, same as content
container div, causing empty message to appear in button instead of panel
- Add hasStatus class to #topBarMain when statusIndicator is active, setting
#topBarTitleName padding-left to 0
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix Legend empty message: scope selector to content container via targetId
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Move Toast.js to design-system, fix --color-a3 text contrast, update AGENTS.md
- Move Toast.js from UserInterface_/components/Toast/ to design-system/components/Toast/
(generic component belongs in design-system, not MMGIS-specific UserInterface_)
- Update all 11 Toast import paths to new location
- Bump --color-a3 in 5 dark themes to pass WCAG AA 4.5:1 contrast for text:
Dark Default #747c81→#81888d, Dark Blue #64748b→#738399,
Dark Warm #8b7a5e→#908064, Dark Mars #8a6a60→#98796f,
Dark Midnight #606088→#7a7a9e
- Update AGENTS.md: document design-system/ vs UserInterface_/ distinction
in project structure and Key Directories
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix topBarTitleName padding override: increase specificity and add !important
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix IdentifierTool deactivation: update icon ID reference in separateFromMMWebGIS
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Hide toolPanelDrag when no tool is open
- Add setToolPanelDragVisible(false) to closeActiveTool() (was only in makeTool toggle-off path)
- Also guard drag handle display on isOpen (toolPanelWidth > 0) as safety net
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Add hover effect to MMGIS logo (opacity + brightness transition)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix MMGIS logo hover: keep full opacity, use subtle background highlight instead
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Selective tile fade: fade on pan/zoom, instant on refresh/reload
- Remove blanket _fadeAnimated toggle from toggleTimeUI (was killing fade
for all tiles while TimeUI was open)
- Monkey-patch GridLayer.redraw, TileLayer.setUrl, and GridLayer._tileReady
to suppress fade via a transient _suppressTileFade map flag
- Set _suppressTileFade in reloadTimeLayers for time-driven reloads
- Flag auto-clears after 300ms so pan/zoom tiles still get the nice fade
- Install pbf dependency (required by CesiumMVTLayer from #942 merge)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Per-layer fade control: time-enabled + shade/viewshed layers never fade
- Replace transient map-level _suppressTileFade with per-layer _noFade flag
- Patch GridLayer._tileReady to check _noFade on the layer instance
- Set _noFade on time-enabled tile layers and data/GL layers at creation
- Set _noFade on Shade and Viewshed tool GL layers
- Non-time-enabled base imagery tiles still fade normally on pan/zoom
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile UI improvements — move hamburger to right menu, show panel toggles, isMobile-driven toolbar layout, desktop-matching scalebar/compass
- Remove left hamburger menu (#topBarMenu), move BottomBar items into
top-right kebab dropdown menu for both mobile and desktop
- Show panel toggles (Viewer/Map/Globe) and account/login UI in mobile
topbar's #topBarRight
- Move toolbar horizontal layout CSS from @media breakpoints to
UserInterfaceMobile_.css (loaded only when isMobile flag is true)
- Remove #mapTopBar @media rule from mmgis.css, add to mobile CSS
- Remove mobile-only simplified scalebar rendering; use full desktop
scalebar with both large and small axes on all viewports
- Remove display:none on .leaflet-control-scalefactor in mobile CSS
- Remove #loginDiv display:none from mobile CSS (React overlay handles it)
- Simplify BottomBarReact container styles (no more absolute positioning)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.28-20260430 [version bump]
* fix: mobile toolbar 40px height, bottomFloatingBar flush, timeUI toggle, scalebar position, hide hotkeys
- Toolbar height 40px, toolButton width 40px, no border-bottom
- toolcontroller_incdiv: no padding-bottom, overflow-y hidden
- bottomFloatingBar: no border-radius, left/right/bottom = 0
- Add MobileTimeUIToggle button on far right of toolbar
- Hide Keyboard Shortcuts from kebab menu on mobile
- Fix scalebar positioning (remove top:48px override in UserInterfaceBridge)
- Set mobileTopSize/topSize to 40 (splitscreens top = 40px, not 50px)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile topBar padding-left 34px
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: update MobileCoordButton topBar paddingLeft from 80px to 34px
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: MobileTimeUIToggle — inline toggle logic, float right, hide from settings on mobile
- Replace broken Coordinates.toggleTimeUI() call with direct jQuery/store toggle
- Float time button right in toolbar
- Hide Time UI toggle from settings modal on mobile (toolbar has it)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: push scalebar/compass/scale up 40px on mobile, keep #timeUI in DOM
- BottomElementPositioner: position mapToolBar, leaflet-bottom-left/right
40px above bottom on mobile (above toolbar)
- Stop removing #timeUI from DOM on mobile so MobileTimeUIToggle works
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile TimeUI — only show endtime, always expanded
- Hide #mmgisTimeUIStartWrapper and StartWrapperFake on mobile via CSS
- Force expanded state (addClass expanded + show) when toggling TimeUI on
- CSS ensures #timeUI.active always shows expanded content on mobile
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile TimeUI opens in tool panel with header, end time, expanded rows
- MobileTimeUIToggle now opens/closes the tool panel via ToolController_
- Closes any active tool before showing TimeUI
- Forces expanded state when opening
- CSS hides start time inputs, positions expanded content properly
- Overrides absolute positioning of expanded content for tool panel flow
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* feat: rewrite separated tools system from jQuery to React components
- Add separatedToolsList/activeSeparatedTools state to Zustand uiStore
- Rewrite SeparatedTools.jsx with glassmorphism panels, CSS Module styling
- Replace SepToolsContainer (setInterval hack) with SepToolButton/SepToolsSection
- Remove ~170 lines of jQuery DOM construction from ToolController_.js
- Fix hardcoded rgba(26,26,27,0.88) to theme-aware var(--color-a-rgb)
- Remove separated tool entries from themeApplier.js
- Remove separated tool overrides from FloatingElements.css
- Move Legend CSS overrides from Toolbar.module.css to SeparatedTools.module.css
- Remove jQuery active-state manipulation from IdentifierTool.js
- Add store sync in Map_.js displayOnStart logic
- Preserve all DOM IDs for backward compatibility (mmgisAPI, tool make())
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.28-20260501 [version bump]
* fix: TimeUI mobile checks — use Zustand store instead of L_.UserInterface_
L_.UserInterface_ is null when TimeUI.init() runs (TimeControl.init is called
before L_.link sets UserInterface_). All 16 isMobile checks now read from
useUIStore.getState().isMobile which is set at startup.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.29-20260501 [version bump]
* fix: move displayOnStart logic from Map_.js to ToolController_.finalizeTools()
- Map_ no longer references specific tools (LegendTool)
- displayOnStart is now handled generically for all separated tools
- Added DOM element polling (tryMake) to handle React render timing
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* revert: remove all TimeUI-related mobile changes
Reverts TimeUI.js and BottomBar.js to development base.
Restores #timeUI DOM removal in UserInterfaceBridge.fina().
Removes MobileTimeUIToggle component from Toolbar.jsx.
Removes TimeUI mobile CSS overrides from UserInterfaceMobile_.css.
Non-TimeUI refinements (toolbar height, scalebar positioning, etc.) preserved.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* simplify: remove DOM polling, use simple setTimeout(0) for auto-open
LegendTool handles its own content lifecycle via subscribeOnLayerToggle.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* feat: mobile TimeUI — fix isMobile detection, staging container, toolbar toggle
- TimeUI.js: import useUIStore and replace all 16 L_.UserInterface_?.isMobile
checks with useUIStore.getState().isMobile (L_.UserInterface_ is null when
TimeUI.init() runs, so mobile conditionals were dead code)
- TimeUI.js: stage mobile #timeUI in hidden #timeUIMobileStaging instead of
placing directly in #tools (which gets cleared by other tools)
- UserInterfaceBridge.js: stop removing #timeUI from DOM on mobile
- Toolbar.jsx: add MobileTimeUIToggle that moves #timeUI between staging and
#tools, opens/closes tool panel via ToolController_
- BottomBar.js: hide TimeUI toggle from settings modal on mobile
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: rescue #timeUI back to staging when another tool opens
Subscribe to activeToolName changes — when a tool becomes active while
TimeUI is showing, move #timeUI back to #timeUIMobileStaging before
the new tool's make() clears #tools.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: remove separatedTool/justification config toggles, fix review issues
- Remove separatedTool checkbox and justification dropdown from Legend
and Identifier config.json (these are always separated, not configurable)
- Remove justification property/code from LegendTool.js, IdentifierTool.js
- Simplify Globe_.js separated tool count (no justification filter)
- Remove justification from Reference-Mission config blueprint
- Update LegendTool help docs and Legend.md documentation
- Add --color-a-rgb fallback (29,31,32) in SeparatedTools.module.css
- Add display:none !important to .panelIdentifier to prevent 12px gap
- Update e2e test comment
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: circular import in TimeUI.js, toolbar/bottomFloatingBar position sync
- TimeUI.js: replace top-level useUIStore import with lazy _getUIStore()
accessor to avoid 'Cannot access useUIStore before initialization'
circular import error at _remakeTimeSlider
- SplitScreens.jsx: skip #timeUI reparenting observer on mobile (mobile
uses MobileTimeUIToggle to manage #timeUI placement in #tools)
- BottomElementPositioner.jsx: unify mobile transition to 0.3s (matches
toolsWrapper and toolbar), guard pxIsTools against undefined
- Toolbar.jsx: align toolbar transition to 0.3s ease-out
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* LegendTool fix empty message
* chore: remove separated tools offset logic from Globe_.js
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: skip _makeHistogram on mobile (no timeline slider, timestamps unset)
_makeHistogram renders inside the timeline slider which doesn't exist
on mobile. Without it, _timelineStartTimestamp is NaN, causing
'Invalid time value' RangeError at toISOString().
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile TimeUI — populate expanded rows, fix Invalid date, fix panel height
- TimeUI.js attachEvents: use _initialStart/_initialEnd on mobile (same
as desktop) instead of L_.TimeControl_ which isn't set yet at init time.
Fixes 'Invalid date' in start/end time inputs.
- TimeUI.js fina: set expanded=true on mobile and call _populateExpandedRows()
so year/month/day/hour rows actually render. Removed position:absolute and
pointer-events:none overrides.
- Toolbar.jsx: set tool panel height to 217px (TimeUI.height) instead of
45% viewport — matches actual TimeUI content height.
- UserInterfaceMobile_.css: expanded content flows naturally (position:relative),
hide start time inputs, allow overflow scroll, flex-wrap topbar.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile TimeUI justify-content center, restore toolbar border-bottom
- Add justify-content: center to #mmgisTimeUIMain on mobile
- Remove border-bottom: none override so toolbar keeps its default border
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile TimeUI overflow hidden, scalebar/compass fixed at 40px offset
- #timeUI overflow-y: hidden (was auto, causing 2px scroll)
- Scalebar/compass/map controls stay at fixed 40px offset (above toolbar)
regardless of tool panel state — no longer shift up by pxIsTools
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Implement multi-tier knowledge architecture
- Restructure AGENTS.md from 745 lines to 106 lines (Tier 1: essential context)
- Create knowledge/ directory with 30+ wiki-style documentation files (Tier 2: deep knowledge)
- Create knowledge/reference/ with 8 detailed reference files (Tier 3: lookup material)
- Move AI-GETTING-STARTED.md and AI-DEVELOPMENT.md to knowledge/
- Update all file references in .specify/templates and blueprints
- Create knowledge/README.md as the full knowledge base index
- Create knowledge/reference/README.md as reference material index
Three-tier knowledge discovery system:
Tier 1: AGENTS.md (~106 lines) - scannable in <2 minutes
Tier 2: knowledge/*.md - deep knowledge on architecture, tools, APIs, DB, infra
Tier 3: knowledge/reference/*.md - coding conventions, API reference, troubleshooting
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.29-20260501 [version bump]
* fix: mobile toolbar active button style matches desktop, fix icon alignment
- All mobile toolbar buttons (ToolButton, MobileCoordButton, MobileTimeUIToggle)
now use display:flex with align-items/justify-content center for proper
vertical icon centering
- MobileCoordButton: changed 'active' class to 'toolButtonActive' to match
the global CSS active style (color-mmgis + color-i background)
- Removed inline color overrides so CSS .toolButtonActive takes effect
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Add Devin knowledge notes from past MMGIS sessions
Include curated lessons learned from past Devin sessions:
- CI/CD: ignore build-arm64/amd64 failures, focus on required checks
- Child sessions: no separate PRs when consolidating
- ENV triple-update rule (.env, sample.env, ENVs.md)
- Error handling: use logger with infrastructure_error for fatal startup errors
- Path traversal security: stay within /Missions, handle subpath serving
- Database initialization architecture and migration patterns
- API authentication behavior across AUTH modes
- Auto-generated MMGIS concept index
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile toolbar active button style, icon alignment, tool deactivation
- Active toolbar buttons get desktop-matching margin (1px 0) and
border-radius (8px) via .toolButton.toolButtonActive CSS rule
- Removed line-height: 40px from .toolButton (flex centering handles
vertical alignment, line-height was pushing icons up)
- MobileCoordButton now watches activeToolName store and deactivates
when another tool opens (fixes coords staying active)
- MobileTimeUIToggle sets activeToolName='MobileTimeUI' when opening
so coords/other buttons can detect it and deactivate
- MobileTimeUIToggle clears activeToolName when closing
- Both custom buttons skip self-deactivation via name check
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix cross-references: convert backtick refs to markdown links, add Devin knowledge notes
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile toolbar icon height 40px, button margins for active padding
- #toolbar .toolButton i: height 40px fixes icon vertical alignment
- #toolbar .toolButton: margin 0 2px gives spacing between buttons
- #toolbar .toolButton.toolButtonActive: margin 1px 2px so active
background has visual padding around the icon
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Rename knowledge/ to .knowledge/ for consistency with .specify/ convention
Dot-prefix signals agent infrastructure (not source code), consistent with
.specify/, .github/, .vscode/ conventions. All cross-references updated.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: mobile toolbar icon line-height 40px, active button padding via height
- Coord and TimeUI button <i> icons get line-height: 40px
- Active buttons: height 34px (vs 40px toolbar) creates visual padding
around the active background, centered by flex align-items
- Buttons get margin: 0 1px for horizontal spacing
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix broken cross-reference: 06.2 -> 06.1-configure-rest-api.md
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: close active tool + cancel deferred cleanup in MobileCoordButton/TimeUI
- MobileCoordButton: call closeActiveTool() before opening, destroy
_pendingCloseTool if set, increment _closeSeq to cancel deferred
tools.innerHTML clear
- MobileTimeUIToggle: same _pendingCloseTool + _closeSeq fix after
closeActiveTool() to prevent 420ms deferred cleanup from wiping
#timeUI after it's placed in #tools
- Removed redundant closeActiveTool() from MobileCoordButton close path
(was being called after destroy, not needed)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: active mobile toolbar buttons 34x34px (square)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Drastically compress .knowledge/ — keep only unique agent content
Remove 33 wiki files that duplicate docs/pages/ content.
Remove 9 reference/ files derivable from source code.
Keep only 5 files (down from 46):
- AI-GETTING-STARTED.md (agent setup walkthrough)
- AI-DEVELOPMENT.md (spec-kit workflow)
- conventions-and-gotchas.md (naming, code style, common issues)
- 12-devin-knowledge-notes.md (CI, auth, DB init, security gotchas)
- README.md (index pointing to docs/pages/ for everything else)
Principle: don't duplicate docs/ — only keep what's uniquely agent-optimized.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Rename to knowledge-notes.md, remove Devin branding and fork-specific CI section
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: hide mmgis-map-logo on mobile
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Restore Database Safety Rules for AI Agents section in AGENTS.md
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: shift compass and map scale 6px to the right (both mobile and desktop)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Add back Important Instructions, code pattern templates, and detailed project structure
- Important Instructions in AGENTS.md: MCP tools, hot-reload, Reference Mission
- .knowledge/code-patterns.md: full directory tree with key directory annotations,
plus copy-paste templates for Express routes, Sequelize models, Tool plugins,
and WebSocket handlers
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Update project structure trees to reflect current filesystem
Add missing directories: tests/, .knowledge/, .specify/, .github/, views/,
private/, spice/, build/, examples/, scripts/middleware.js.
Both abbreviated (AGENTS.md) and detailed (.knowledge/code-patterns.md) trees
now match the actual repo layout.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.30-20260501 [version bump]
* Add Layers_.js to project structure (key singleton L_)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix project structure: correct API layout, frontend modules, code templates
API/Backend/ uses feature-domain modules (Draw/, Users/, Config/, etc.)
with setup.js + routes/ + models/ per feature — not APIs/ or Databases/.
Frontend essence/ has Components/, Helpers/, LandingPage/, mmgisAPI/,
services/ — not Ancillary/. Basics/ includes all singletons (Globe_,
Formulae_, ToolController_, Viewer_, ComponentController_, Test_).
Code templates updated to match actual patterns (setup.js, module.exports).
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* refactor: remove test infrastructure (Test_ module, testModules, DrawTool.test)
- Delete src/essence/Basics/Test_/ directory
- Delete src/essence/Tools/Draw/DrawTool.test.js
- Remove Test_ import and Shift+T keydown handler from essence.js
- Remove tests key from Draw tool config.json
- Remove testModules generation logic from API/updateTools.js
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.31-20260501 [version bump]
* style: move Cesium link button to top-right and match Leaflet zoom button styling
- Change control container from top-left to top-right positioning
- Update button size from 26px to 30px to match Leaflet zoom controls
- Use CSS variables (--color-a, --color-f, --color-mmgis) instead of hardcoded colors
- Add border-radius and box-shadow matching Leaflet control appearance
- Update hover/inactive states to use themed colors
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: anchor map logo to viewport instead of Leaflet map panel
- Change MapLogo parent from .leaflet-bottom.leaflet-right to #main-container
- Switch CSS position from absolute to fixed for viewport anchoring
- Add explicit bottom-offset positioning in BottomElementPositioner (desktop)
- Add explicit bottom-offset positioning in BottomElementPositioner (mobile)
- Logo stays at viewport right edge regardless of open side panels
- Retains smooth bottom offset transitions when bottom bar appears
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* docs: remove references to deleted test infrastructure (Test_, DrawTool.test)
- Remove Test_/ from project structure in .knowledge/code-patterns.md
- Remove DrawTool.test.js references from specs/006 spec, plan, and tasks
- Remove Draw Tool Testing section from tasks.md
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.32-20260501 [version bump]
* fix: append logo to document.body to avoid filter containing block
#main-container has a CSS filter property which creates a new containing
block per the CSS spec, causing position:fixed to behave like absolute.
Appending to document.body ensures true viewport-fixed positioning.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix: prevent mobile topBarTitleName text wrapping by replacing max-width with white-space: nowrap
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 4.3.33-20260501 [version bump]
* chore: bump version to 5.0.0 and update changelog
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* refactor(ui): move Screenshot/Fullscreen to BottomBar, About to TopBar kebab
TopBar kebab menu now contains only Keyboard Shortcuts, Settings, and About
(About now shows on both desktop and mobile).
BottomBarReact now renders Screenshot, Fullscreen, and Copy Link buttons
(top to bottom) following the same IconButton + Tooltip pattern. The
About button has been removed from BottomBarReact.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.1-20260505 [version bump]
* feat(mobile): enforce exclusive panel toggling on mobile in TopBar
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.1-20260505 [version bump]
* style: reposition LithoSphere globe controls to match Leaflet/Cesium theme
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.1-20260505 [version bump]
* feat(topbar): hide Viewer/Globe toggles based on configured panels
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style(bottombar): reorder buttons (Copy Link, Screenshot, Fullscreen) and unify size
Reorder the BottomBarReact buttons top-to-bottom to: Copy Link, Screenshot,
Fullscreen.
Move the 24x24 button sizing from the #topBarLink id selector in mmgis.css
into the .barButton class in BottomBarReact.module.css so all three buttons
share the same compact size as the original Copy Link button. Drop the now
redundant #topBarLink rule.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style(bottombar): increase padding-bottom to 12px and button margin to 3px 0
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style: rearrange globe controls — compass top-right circular, nav row, vertical column, panels open left
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.2-20260505 [version bump]
* chore: bump version to 5.0.2-20260505 [version bump]
* style: anchor observe settings panel right:34px and float nav hover panels
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* feat(theming): add 5 new themes, --color-shadow variable, and configure ThemePreview
- Add Dark Terra, Dark Nebula, Dark Lunar, Dark Supernova, Light Botanical themes
- Add --color-shadow CSS variable to every theme + :root fallback
- Replace hardcoded rgba shadow colors with var(--color-shadow) in TopBar,
Toolbar, SeparatedTools, ToolPanel, FloatingElements, Dropdown, Modal,
and SplitScreens
- Add Custom shadowcolor color picker in tab-ui-config and apply it via Stylize
- Add ThemePreview component (configure/src) wired through Maker.js as
a new 'themepreview' row type so the configure UI shows a live mini
mockup of the selected theme
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.2-20260505 [version bump]
* fix(configure/ThemePreview): tighten top spacing and live-preview Custom theme
- Pull the preview up by 12px so the gap below the theme dropdown is tighter.
- Read the Custom color pickers (look.primarycolor / secondarycolor /
tertiarycolor / accentcolor / shadowcolor / topbarcolor / toolbarcolor /
mapcolor) from the configuration and overlay them on Dark Default so
the preview reflects Custom theme edits live, matching Stylize.js's
runtime behavior.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.3-20260505 [version bump]
* feat(themes): add Dark Heliosphere, Dark Monokai, and Light Solarized
- Dark Heliosphere: deep night purple surface with corona-orange accent.
- Dark Monokai: warm graphite surface with lime accent (Monokai-inspired).
- Light Solarized: classic solarized base3/base02 with blue accent.
Mirror added to configure/src/themes/themes.js for the ThemePreview, and
the three names appended to the Color Theme dropdown options.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix(coordinates): respect time.initiallyOpen when live deep-link is set
* chore: bump version to 5.0.3-20260505 [version bump]
* refactor(theming): remove Custom theme + per-field color overrides
- Drop the 'Custom' option from the Color Theme dropdown.
- Remove all Custom Color Options (look.primarycolor, .secondarycolor,
.tertiarycolor, .accentcolor, .bodycolor, .topbarcolor, .toolbarcolor,
.mapcolor, .hightlightcolor, .shadowcolor) from tab-ui-config.json.
- Strip the matching DOM/CSS-variable override block from Stylize.js;
Stylize now just applies the selected preset theme (and the page logo).
- Drop the empty bodycolor/topbarcolor/toolbarcolor/mapcolor/shadowcolor
defaults from API/templates/config_template.js.
- Simplify ThemePreview to render the selected preset directly — no
Custom branch, no overlay logic.
Preset themes cover all the looks we want and keep the configure surface
much smaller.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style(time-ui): round corners on TimeUI shell, action wrappers, mode dropdown
- #timeUI: 10px border-radius on the outer time control bar.
- #mmgisTimeUIActionsLeft / #mmgisTimeUIActionsRight: 10px border-radius
so the action clusters sit as rounded chips.
- #mmgisTimeUIActionsRight > div (excluding #mmgisTimeUIPresent): 10px
border-radius on each action button so they match the wrapper.
- #mmgisTimeUIModeDropdown: 40px height + 10px border-radius to align
with the rest of the bar; clear the dropy default border-color so the
rounded edge isn't outlined.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.4-20260505 [version bump]
* feat(configure): mark light themes as (experimental) in dropdown label
Light themes still have outstanding contrast issues, so flag them in the
Color Theme dropdown without changing the saved value.
- Maker dropdown now accepts options as either a plain string (current
behavior) or { value, label } so the rendered label can differ from
the persisted value.
- tab-ui-config switches the six light themes to { value, label } form
with '(experimental)' appended to the label only. Existing mission
configs that already saved 'Light Default' etc. continue to match.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Fix timeUI border radius
* fix(mobile): rescue #timeUI before tool make() destroys it
Clicking Layers -> Time -> Layers -> Time on mobile caused the bottom
panel to render LayersTool content with TimeUI height. The #timeUI DOM
element was destroyed when LayersTool.make() called $('#tools').empty(),
before the async React useEffect in MobileTimeUIToggle could rescue it
to its staging container.
- ToolController_.makeTool: synchronously move #timeUI from #tools back
to #timeUIMobileStaging (and reset TimeUI store flags) on mobile,
before invoking the new tool's make().
- MobileTimeUIToggle.handleClick: defensive fallback that re-initializes
TimeUI if #timeUI no longer exists when the toggle is activated.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix(mobile): move re-initialized #timeUI from staging into #tools
TimeUI.init() on mobile appends the new #timeUI to the hidden
#timeUIMobileStaging container, so the fallback branch must also move
it into #tools — otherwise the user sees an empty tool panel after
the destroyed-element recovery path.
Caught by Devin Review.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix(mobile): preserve #timeUI when Coordinates tool empties #tools
On mobile, opening or closing the Coordinates tool runs
$('#tools').empty() inside interfaceWithMMWebGIS / separateFromMMWebGIS.
After the previous PR commits, clicking Coordinates -> Time still left
the bottom panel empty because:
- Coordinates.make() empties #tools while #timeUI is in staging (fine
on its own), but the Coordinates teardown that fires after the user
switches to the Time toggle (via MobileCoordButton's useEffect on
activeToolName change) calls Coordinates.destroy() ->
separateFromMMWebGIS(), which empties #tools wholesale and destroys
the freshly-placed #timeUI.
Add a rescueMobileTimeUI() helper that moves #timeUI from #tools back
to #timeUIMobileStaging before each tools.empty() call in Coordinates,
mirroring the rescue already done in ToolController_.makeTool().
Coordinates -> Time now correctly shows the TimeUI.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* fix(mobile): harden TimeUI fallback recovery (call fina(), de-dupe popovers)
Devin Review correctly flagged that the safety-net path in
MobileTimeUIToggle.handleClick was producing a partially-broken TimeUI
when it fired:
- TimeUI.init() unconditionally appends a new #timeUIPlayPopover_global
to <body>, so a second init() left two elements with the same id.
- TimeUI.init() alone does not wire up date pickers or per-button click
handlers — that's TimeUI.fina()'s job. Without fina(), the recovered
TimeUI rendered visually but Play / Previous / Next / Fit / Follow /
Present / Expand were all dead.
Before re-initializing, remove the stale #timeUIPlayPopover_global and
#timeUIQuickSelectPopover_global divs to avoid duplicate ids. After the
new #timeUI is moved into #tools, call TimeUI.fina() to populate the
date pickers, attach the button click handlers, build the histogram,
and populate the expanded mobile rows.
Some delegated body/document handlers in attachEvents() will still be
duplicated on this path; that is acceptable for a degraded recovery
that should never run in practice now that the primary rescues in
ToolController_.makeTool() and Coordinates.js cover all known paths.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.5-20260505 [version bump]
* fix(mobile): Coordinates teardown only removes its own DOM
The previous Coordinates fix was racing with itself: after the Time
toggle synchronously moved #timeUI into #tools, MobileCoordButton's
useEffect (triggered by the activeToolName change) ran on the next
React tick and called L_.Coordinates.destroy(). That called
separateFromMMWebGIS(), whose rescue moved #timeUI right back into the
hidden staging div before tools.empty() — so the bottom panel ended up
empty even though the time toggle was 'active'.
Make separateFromMMWebGIS selective: only remove the
Coordinates-specific DOM (#coordUIHeader and #CoordinatesDiv) instead
of wiping all of #tools. Any other content already in #tools (e.g.
#timeUI placed there by the Time toggle) is left alone.
interfaceWithMMWebGIS still keeps the rescue + tools.empty() pattern
on the open path so Coordinates always starts from a clean panel.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Bump DrawTool Temporal Drawings upward
* chore: bump version to 5.0.6-20260505 [version bump]
* chore: reset version to 5.0.0
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* test(e2e): fix 9 pre-existing failures (test-only changes)
- mmgis-api.spec.js: add form-fill login under AUTH=local; serialize
describe to avoid concurrent-login race in the session store
- coordinates.spec.js: TimeUI toggle was moved from the coordinates bar
to the Settings modal; navigate via topbar kebab menu and assert the
checkbox is rendered
- widgets.spec.js: target .leaflet-control-zoom-in/-out specifically;
the bare .leaflet-control-zoom class is also used by the home/reset
control, so the original assertion was always false
- sites.spec.js: scope panel selector to #toolPanel; both the toolbar
icon and the panel container share id="SitesTool"
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.1-20260505 [version bump]
* Revert "chore: bump version to 5.0.1-20260505 [version bump]"
This reverts commit 4880204c1163be5d1d7fa96d14a0ed018c6f586c.
* fix: prevent filter operator dropdown clipping in Layers panel
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.1-20260507 [version bump]
* revert: keep dropy openUp:true for operator dropdowns
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* Revert "chore: bump version to 5.0.1-20260507 [version bump]"
This reverts commit d67c369ed437e47d658ae051348d377978dc48ed.
* chore: bump version to 5.0.1-20260507 [version bump]
* Revert "chore: bump version to 5.0.1-20260507 [version bump]"
This reverts commit 29565ed829a55e9c241a789c9a3901d11cb5ca67.
* chore: bump version to 5.0.1-20260507 [version bump]
* Revert "chore: bump version to 5.0.1-20260507 [version bump]"
This reverts commit 50e357604ebe9378564619b34c508b63cfb62c1d.
* chore: bump version to 5.0.1-20260507 [version bump]
* chore: bump version to 5.0.2-20260511 [version bump]
* fix: render Globe panel immediately on first open without window resize
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.3-20260511 [version bump]
* feat: add theme borders to panels and gradient backgrounds to splitters
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.4-20260511 [version bump]
* style: bump split shadow gradient opacity to 0.4
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style: hotkeys modal 3-col grid + smaller leaflet zoom button gap
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style: prevent hotkey label/value wrapping (ellipsis instead)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style: hotkeys modal single column, no wrap, no truncation
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.4-20260511 [version bump]
* style: hotkeys modal dividers, invert title/subtitle colors, rename title, margin above subtitles
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style: move splitter gradient to themed CSS class, restore hover feedback
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.5-20260511 [version bump]
* style: hotkeys section titles use --color-h (matches rest of app)
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.5-20260511 [version bump]
* fix: guard Globe_.init() inside rAF to prevent double instantiation
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.6-20260512 [version bump]
* feat(plugins): per-plugin deps, lazy tool loading, validation, shared discovery
Phase 3 — Plugin config validation + override warnings:
- New API/pluginValidation.js with validatePluginConfig() for tool, component,
and backend manifests. Validates required fields (name, paths), object/string
shape of paths, dependencies block (npm/python.pip/python.conda), and warns
on unknown top-level fields.
- updateTools()/updateComponents() now skip invalid plugins and emit override
warnings (matching what components already logged for tools).
Phase 2 — Shared discoverPlugins() utility:
- New API/pluginDiscovery.js consolidates the duplicated scanning logic from
updateTools(), updateComponents(), and getBackendSetups(). Supports exact-
name and substring container patterns, JSON/require/no-op loaders, and skips
dot/underscore-prefixed dirs.
- updateTools.js and setups.js refactored on top of the shared helper.
Phase 1 — Per-plugin dependency declaration + build-time aggregation:
- Plugin config.json may now declare a 'dependencies' block (npm + python.pip +
python.conda). validatePluginConfig() also validates this shape.
- New scripts/resolve-plugin-deps.js scans every tool/component/backend plugin
and writes plugin-package.json, plugin-python-requirements.txt, and
plugin-conda-deps.txt. Detects version conflicts and fails loudly.
- scripts/build.js calls resolvePluginDeps() before updateTools().
- Dockerfile installs the aggregated plugin npm and pip deps after the root
npm ci, using --no-save / --no-package-lock / --ignore-scripts so the root
lockfile is untouched.
- Animation tool migrated: ffmpeg/gifshot/html2canvas now declared in its
config.json (kept in root package.json for transitional compat).
- Generated artifacts gitignored.
Phase 4 — Lazy loading of tool bundles:
- updateTools() now emits dynamic-import arrow functions in the generated
src/pre/tools.js with webpackChunkName hints so each tool is split into
its own chunk (Kinds stays static because it's required synchronously).
- ToolController_ gains ensureToolLoaded(name) and getLoadedTool(name) helpers
and makeTool is async; init/finalizeTools and the separated-tool auto-open
flow are updated to handle lazy modules.
- Toolbar.jsx, SeparatedTools.jsx, SitesTool.js, and Layers_.js migrated to
resolve LayersTool/etc. via the new helpers instead of poking toolModules
directly.
Tests & docs:
- tests/fixtures/test-plugin-tools/{TestPlugin,InvalidPlugin,OverridePlugin}
+ tests/helpers/plugin-helpers.js with install/uninstall helpers.
- New unit specs: pluginValidation, pluginDiscovery, updateTools,
resolvePluginDeps, toolLazyLoading (57 tests, all passing).
- CONTRIBUTING.md and docs/pages/Contributing/Contributing.md updated with
schema, override behaviour, dependency declaration, build-time aggregation,
conflict detection, and Docker integration.
* chore: bump version to 5.0.7-20260512 [version bump]
* fix: make Globe_.init() idempotent against multi-init
Globe_.init() previously constructed a fresh GlobeRenderer on every call,
which after #71 could happen multiple times for a single toggle (uiStore
setTimeout + TopBar rAF). Each extra construction appends another
.cesium-widget / _lithosphere_scene to #globe and leaves event handlers
wired to dereferenced renderer state, which has been observed to break
LithoSphere globe control buttons on configurations where the globe panel
starts closed at boot.
Add a top-of-init() guard that bails out and calls invalidateSize() when
a renderer already exists. Single small, surgical change; no behavior
change for the !L_.hasGlobe mock-swap path or for first-time construction.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* chore: bump version to 5.0.7-20260512 [version bump]
* test(plugins): generate src/pre/tools.js on demand in toolLazyLoading spec
The Playwright unit-tests CI step runs before `npm run build` so the
gitignored `src/pre/tools.js` artifact does not yet exist on disk.
Add a beforeAll hook that invokes `updateTools()` to regenerate it
when missing, keeping the spec self-contained on both CI and dev
machines that already built locally.
* fix(tools): defensive getTool() + preload flag for cross-referenced tools
Devin Review flagged a behavioural regression introduced by Phase 4:
`ToolController_.getTool(name)` previously always returned a method-
callable object (real module or `{ use(){} }` stub) because every tool
was statically imported. After Phase 4, unresolved lazy loaders are
`() => import(...)` functions, so callers like `Map_.getTool('InfoTool').use(...)`,
`mmgisAPI.getTool('DrawTool').filesOn`, and `LegendTool` calling
`LayersTool.populateCogScale` would crash with TypeError until the
target tool was opened.
Two fixes:
1. **Defensive getTool()**: Returns the legacy fallback stub when the
tool module is still a lazy-loader function, and fires off
`ensureToolLoaded(name)` in the background so subsequent calls see
the resolved module. Prevents all crashes immediately.
2. **`preload: true` config flag**: Tools reached synchronously from
other code paths (Info, Draw, Layers, Chemistry) now declare
`"preload": true` in their `config.json`. `ToolController_.init()`
calls `preloadEagerTools()` which fires `ensureToolLoaded` for
every such tool right after toolbar setup — the chunks download
in parallel with the rest of the page becoming interactive, so by
the time a user clicks a feature the InfoTool module is already
resolved.
`validatePluginConfig` now accepts `preload` as a known tool field;
CONTRIBUTING.md and docs/pages/Contributing/Contributing.md updated to
document when to set it. Added a unit test covering the defensive
getTool behaviour and the `preload` propagation through
`toolConfigs`.
* chore: bump version to 5.0.8-20260512 [version bump]
* revert(plugins): remove Phase 4 lazy tool loading and preload mechanism
Phase 4 lazy emission caused cross-tool consumers (Map_ feature-click,
mmgisAPI, LegendTool) to receive raw '() => import(...)' arrows from
ToolController_.getTool(), breaking InfoTool open. Reverting to the
pre-Phase-4 behavior of static tool imports.
- API/updateTools.js: generated src/pre/tools.js now emits
'import FooTool from ...' for every tool (Kinds stays static too).
- ToolController_.js: getTool/makeTool back to sync; ensureToolLoaded,
getLoadedTool, preloadEagerTools deleted; separated-tool auto-open
flow simplified to direct sync calls.
- Toolbar.jsx, SeparatedTools.jsx, Layers_.js: revert async/lazy
patterns to sync ToolController_.toolModules[name] access.
- API/pluginValidation.js: drop 'preload' from KNOWN_FIELDS.
- src/essence/Tools/{Info,Draw,Layers,Chemistry}/config.json: drop
'preload: true'.
- CONTRIBUTING.md + docs: remove preload documentation.
- tests/unit/toolLazyLoading.spec.js: rewrite to verify static
imports instead of lazy loaders.
Also: log standard backends at startup (parity with plugin backends
and with tools/components), so all backends now produce
'info Loaded backend: <name> from <container>' at boot.
Phases 1-3 (per-plugin dependency aggregation, shared discoverPlugins,
config validation + override warnings) are unaffected.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* feat(logger): new 'loaded' level (purple bg) for tool/component/backend startup
Previously the 'Loaded tool/component/backend: X from Y' lines used
the generic blue 'info' tag. They now use a dedicated 'loaded' level
rendered with a purple (#a855f7) background, so plugin discovery
output is visually distinct from other info messages.
- API/logger.js: add 'loaded' case to the dev-mode switch (white text
on purple bg) and suppress the redundant 'Caller:' echo for it
(matches how 'info' and 'success' are handled).
- API/updateTools.js: registerPlugin now logs at level 'loaded'.
Drops the redundant 'Loaded ' prefix since the level tag now reads
'loaded'.
- API/setups.js: standard and plugin backend startup logs use the
new level, same drop of the 'Loaded ' prefix.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* feat(logs): 'Plugging in Tools/Components/Backends...' headings
Rename the cyan banner messages in scripts/build.js and scripts/server.js
from 'Updating Tools...' / 'Updating Components...' to 'Plugging in
Tools...' / 'Plugging in Components...' so the headings match the
plugin terminology used everywhere else (plugin-package.json,
discoverPlugins, etc.).
Also add a matching 'Plugging in Backends...' banner before
setups.getBackendSetups() in scripts/server.js so backends get an
equivalent title block to tools and components.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* style(logs): cyan banner lines lead with a blank line instead of trailing one
Move the \n from the end to the beginning of every cyan banner in
scripts/build.js and scripts/server.js (Resolving Plugin Dependencies,
Plugging in Tools/Components/Backends, Validating Environment
Variables, Starting websocket, Starting the development server) so
that the blank line visually separates each section above its title
rather than below it.
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
* feat(plugins): postinstall hook auto-installs plugin npm deps
Plain `npm install` (or `np…1 parent bd540cf commit 740a572
6 files changed
Lines changed: 8 additions & 8 deletions
File tree
- blueprints/Missions/Reference-Mission
- configure
- src/metaconfigs
- src/essence/Tools/Measure
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3244 | 3244 | | |
3245 | 3245 | | |
3246 | 3246 | | |
3247 | | - | |
| 3247 | + | |
3248 | 3248 | | |
3249 | 3249 | | |
3250 | 3250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
771 | 771 | | |
772 | 772 | | |
773 | 773 | | |
774 | | - | |
775 | | - | |
| 774 | + | |
| 775 | + | |
776 | 776 | | |
777 | 777 | | |
778 | 778 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
901 | 901 | | |
902 | 902 | | |
903 | 903 | | |
904 | | - | |
| 904 | + | |
905 | 905 | | |
906 | 906 | | |
907 | 907 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
51 | | - | |
| 50 | + | |
| 51 | + | |
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| |||
0 commit comments