feat(dashboard): move edit mode controls to menu permanently
Reduces header button crowding by keeping edit controls in menu at all screen sizes. Changes: - Add .rpg-menu-only-btn class to Add/Export/Import/Done buttons - Remove display toggling from EditModeManager (simpler state machine) - Update HeaderOverflowManager to: - Always hide menu-only buttons (never show inline) - Mark them as available for menu (wasVisible = 'true') - Filter menu items based on edit mode state - Add setEditModeManager() for edit state access - Wire editModeManager to headerOverflowManager in integration Result: - Full mode: 6 visible buttons (was 10 with edit mode active) - Overflow mode: 3 priority + menu with 3 standard + 4 edit (when active) - Compact mode: 3 priority + hamburger with all actions (filtered by edit state) Edit mode controls (Add Widget, Export, Import, Done) now only appear in dropdown/hamburger menu, never inline. This creates cleaner visual hierarchy and eliminates layout jumping when toggling edit mode. Existing menu refresh on edit mode toggle (line 305) ensures menu updates with correct items when entering/exiting edit mode.
This commit is contained in:
@@ -127,6 +127,11 @@ export async function initializeDashboard(dependencies) {
|
||||
if (headerRight) {
|
||||
headerOverflowManager = new HeaderOverflowManager(headerRight);
|
||||
headerOverflowManager.init();
|
||||
|
||||
// Wire up editModeManager for menu filtering
|
||||
if (dashboardManager?.editManager) {
|
||||
headerOverflowManager.setEditModeManager(dashboardManager.editManager);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[RPG Companion] Dashboard v2 initialized successfully');
|
||||
|
||||
@@ -37,19 +37,19 @@
|
||||
<i class="fa-solid fa-arrow-down-short-wide"></i>
|
||||
</button>
|
||||
|
||||
<button id="rpg-dashboard-add-widget" class="rpg-dashboard-btn rpg-add-widget-btn rpg-overflow-btn" style="display: none;" title="Add Widget" aria-label="Add widget">
|
||||
<button id="rpg-dashboard-add-widget" class="rpg-dashboard-btn rpg-add-widget-btn rpg-overflow-btn rpg-menu-only-btn" style="display: none;" title="Add Widget" aria-label="Add widget">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</button>
|
||||
|
||||
<button id="rpg-dashboard-export-layout" class="rpg-dashboard-btn rpg-export-btn rpg-overflow-btn" style="display: none;" title="Export Layout" aria-label="Export layout">
|
||||
<button id="rpg-dashboard-export-layout" class="rpg-dashboard-btn rpg-export-btn rpg-overflow-btn rpg-menu-only-btn" style="display: none;" title="Export Layout" aria-label="Export layout">
|
||||
<i class="fa-solid fa-download"></i>
|
||||
</button>
|
||||
|
||||
<button id="rpg-dashboard-import-layout" class="rpg-dashboard-btn rpg-import-btn rpg-overflow-btn" style="display: none;" title="Import Layout" aria-label="Import layout">
|
||||
<button id="rpg-dashboard-import-layout" class="rpg-dashboard-btn rpg-import-btn rpg-overflow-btn rpg-menu-only-btn" style="display: none;" title="Import Layout" aria-label="Import layout">
|
||||
<i class="fa-solid fa-upload"></i>
|
||||
</button>
|
||||
|
||||
<button id="rpg-dashboard-done-edit" class="rpg-dashboard-btn rpg-done-edit-btn rpg-overflow-btn" style="display: none;" title="Exit Edit Widget Mode" aria-label="Done editing">
|
||||
<button id="rpg-dashboard-done-edit" class="rpg-dashboard-btn rpg-done-edit-btn rpg-overflow-btn rpg-menu-only-btn" style="display: none;" title="Exit Edit Widget Mode" aria-label="Done editing">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
|
||||
|
||||
@@ -59,18 +59,10 @@ export class EditModeManager {
|
||||
// Store original layout for cancel
|
||||
this.originalLayout = this.captureLayout();
|
||||
|
||||
// Hide edit mode button, show done button and edit mode controls
|
||||
// Hide edit mode button (menu-only controls managed by headerOverflowManager)
|
||||
const editModeBtn = document.querySelector('#rpg-dashboard-edit-mode');
|
||||
const doneBtn = document.querySelector('#rpg-dashboard-done-edit');
|
||||
const addWidgetBtn = document.querySelector('#rpg-dashboard-add-widget');
|
||||
const exportBtn = document.querySelector('#rpg-dashboard-export-layout');
|
||||
const importBtn = document.querySelector('#rpg-dashboard-import-layout');
|
||||
|
||||
if (editModeBtn) editModeBtn.style.display = 'none';
|
||||
if (doneBtn) doneBtn.style.display = '';
|
||||
if (addWidgetBtn) addWidgetBtn.style.display = '';
|
||||
if (exportBtn) exportBtn.style.display = '';
|
||||
if (importBtn) importBtn.style.display = '';
|
||||
|
||||
// Disable content editing to prevent keyboard from messing up layout
|
||||
this.disableContentEditing();
|
||||
@@ -112,18 +104,10 @@ export class EditModeManager {
|
||||
// Re-enable content editing
|
||||
this.enableContentEditing();
|
||||
|
||||
// Show edit mode button, hide done button and edit controls
|
||||
// Show edit mode button (menu-only controls managed by headerOverflowManager)
|
||||
const editModeBtn = document.querySelector('#rpg-dashboard-edit-mode');
|
||||
const doneBtn = document.querySelector('#rpg-dashboard-done-edit');
|
||||
const addWidgetBtn = document.querySelector('#rpg-dashboard-add-widget');
|
||||
const exportBtn = document.querySelector('#rpg-dashboard-export-layout');
|
||||
const importBtn = document.querySelector('#rpg-dashboard-import-layout');
|
||||
|
||||
if (editModeBtn) editModeBtn.style.display = '';
|
||||
if (doneBtn) doneBtn.style.display = 'none';
|
||||
if (addWidgetBtn) addWidgetBtn.style.display = 'none';
|
||||
if (exportBtn) exportBtn.style.display = 'none';
|
||||
if (importBtn) importBtn.style.display = 'none';
|
||||
|
||||
// Remove edit class from container
|
||||
this.container.classList.remove('edit-mode');
|
||||
|
||||
@@ -27,6 +27,7 @@ export class HeaderOverflowManager {
|
||||
this.menuOpen = false;
|
||||
this.resizeObserver = null;
|
||||
this.resizeTimeout = null;
|
||||
this.editModeManager = null; // Reference to EditModeManager for menu filtering
|
||||
|
||||
// Element references
|
||||
this.priorityButtons = null;
|
||||
@@ -42,6 +43,14 @@ export class HeaderOverflowManager {
|
||||
this.boundClickOutside = this.handleClickOutside.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set EditModeManager reference for menu filtering
|
||||
* @param {EditModeManager} editModeManager - Edit mode manager instance
|
||||
*/
|
||||
setEditModeManager(editModeManager) {
|
||||
this.editModeManager = editModeManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the overflow manager
|
||||
*/
|
||||
@@ -138,18 +147,24 @@ export class HeaderOverflowManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Mode: Show all buttons
|
||||
* Full Mode: Show all buttons except menu-only
|
||||
*/
|
||||
setFullMode() {
|
||||
// Show all overflow buttons
|
||||
// Show all overflow buttons except menu-only ones
|
||||
this.overflowButtons.forEach(btn => {
|
||||
// Only show buttons that don't have inline display:none in the template
|
||||
const inlineStyle = btn.getAttribute('style');
|
||||
if (!inlineStyle || !inlineStyle.includes('display: none')) {
|
||||
btn.style.display = '';
|
||||
// Menu-only buttons always stay hidden (managed by menu)
|
||||
if (btn.classList.contains('rpg-menu-only-btn')) {
|
||||
btn.style.display = 'none';
|
||||
btn.dataset.wasVisible = 'true'; // Mark as available for menu
|
||||
} else {
|
||||
// Only show buttons that don't have inline display:none in the template
|
||||
const inlineStyle = btn.getAttribute('style');
|
||||
if (!inlineStyle || !inlineStyle.includes('display: none')) {
|
||||
btn.style.display = '';
|
||||
}
|
||||
// Clear the wasVisible flag for non-menu-only buttons
|
||||
delete btn.dataset.wasVisible;
|
||||
}
|
||||
// Clear the wasVisible flag
|
||||
delete btn.dataset.wasVisible;
|
||||
});
|
||||
|
||||
// Hide menu buttons
|
||||
@@ -164,8 +179,13 @@ export class HeaderOverflowManager {
|
||||
// Hide overflow buttons (will be in dropdown)
|
||||
// Store original visibility before hiding
|
||||
this.overflowButtons.forEach(btn => {
|
||||
const computedStyle = window.getComputedStyle(btn);
|
||||
btn.dataset.wasVisible = computedStyle.display !== 'none' ? 'true' : 'false';
|
||||
// Menu-only buttons are always available in menu
|
||||
if (btn.classList.contains('rpg-menu-only-btn')) {
|
||||
btn.dataset.wasVisible = 'true';
|
||||
} else {
|
||||
const computedStyle = window.getComputedStyle(btn);
|
||||
btn.dataset.wasVisible = computedStyle.display !== 'none' ? 'true' : 'false';
|
||||
}
|
||||
btn.style.display = 'none';
|
||||
});
|
||||
|
||||
@@ -184,8 +204,13 @@ export class HeaderOverflowManager {
|
||||
// Hide all overflow buttons
|
||||
// Store original visibility before hiding
|
||||
this.overflowButtons.forEach(btn => {
|
||||
const computedStyle = window.getComputedStyle(btn);
|
||||
btn.dataset.wasVisible = computedStyle.display !== 'none' ? 'true' : 'false';
|
||||
// Menu-only buttons are always available in menu
|
||||
if (btn.classList.contains('rpg-menu-only-btn')) {
|
||||
btn.dataset.wasVisible = 'true';
|
||||
} else {
|
||||
const computedStyle = window.getComputedStyle(btn);
|
||||
btn.dataset.wasVisible = computedStyle.display !== 'none' ? 'true' : 'false';
|
||||
}
|
||||
btn.style.display = 'none';
|
||||
});
|
||||
|
||||
@@ -209,8 +234,20 @@ export class HeaderOverflowManager {
|
||||
: this.overflowButtons;
|
||||
|
||||
// Filter visible buttons (only include buttons that were visible before being hidden)
|
||||
// Also filter menu-only buttons based on edit mode state
|
||||
const isEditMode = this.editModeManager?.isEditMode || false;
|
||||
const visibleButtons = buttonsToShow.filter(btn => {
|
||||
return btn.dataset.wasVisible === 'true';
|
||||
// Check if button was marked as visible
|
||||
if (btn.dataset.wasVisible !== 'true') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Menu-only buttons only show when in edit mode
|
||||
if (btn.classList.contains('rpg-menu-only-btn')) {
|
||||
return isEditMode;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (visibleButtons.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user