Repository: CollaboraOnline/online
Pull request #11334: status bar: remove right and left arrows
Author: login: banobepascal
Labels: name: draft
name: CODE "red"
Created: 2025-03-13T11:24:45Z | Merged: 2025-03-31T09:43:50Z

Change-Id: Ied57f580bc7c1ea5d488e935f5f906f0935bd3cf

* Target version: master 

### Previews
[Screencast from 25-03-25 04:40:39.webm](https://github.com/user-attachments/assets/199992d7-fbc2-4032-97a5-abb1f9bc7544)


### Summary
- Removes the left and right arrows from the status bar to address inconsistencies after removing default states.
- The arrows also block the Zoom "+" which is frustrating to users as they would need to double click the arrow to remove it and click zoom +




Diff:
diff --git a/browser/css/cool.css b/browser/css/cool.css
index 8deb0db9a5fba..322f095f93a8a 100644
--- a/browser/css/cool.css
+++ b/browser/css/cool.css
@@ -462,6 +462,13 @@ body {
 	color: var(--color-main-text);
 }
 
+@media screen and (max-width: 500px) {
+	#search-input {
+		width: 100px;
+	}
+}
+
+
 .cool-character {
 	table-layout: fixed;
 	font: 17px/1.5 'Helvetica Neue', Arial, Helvetica, sans-serif;
diff --git a/browser/css/jsdialogs.css b/browser/css/jsdialogs.css
index 5181bca718b76..5777e73c39286 100644
--- a/browser/css/jsdialogs.css
+++ b/browser/css/jsdialogs.css
@@ -291,7 +291,7 @@ td.jsdialog > [id^='table-box']:not(.sidebar) {
 #toolbar-down .ui-badge,
 #toolbar-down .unolabel {
 	font-family: var(--cool-font);
-	font-size: var(--default-font-size);
+	font-size: var(--default-font-size) !important;
 	color: var(--color-status-badge) !important;
 }
 
@@ -2024,6 +2024,11 @@ input[type='number']:hover::-webkit-outer-spin-button {
 	background-color: transparent !important;
 	border-color: transparent;
 }
+
+#toolbar-down  .jsdialog .ui-edit-container{
+	place-content: center;
+}
+
 /* Formula Wizard */
 #FormulaDialog .ui-tabs-root {
 	background-color: var(--color-background-tabs-group);
@@ -2295,6 +2300,11 @@ kbd,
 #showcomments-container[default-state='true'],
 #insertmode-container[default-state='true'],
 #permissionmode-container[default-state='true'],
+#documentstatus-container[default-state='true'],
 #statusselectionmode-container[default-state='true'] {
 	display: none !important;
+}
+
+.status-hidden {
+	display: none !important;
 }
\ No newline at end of file
diff --git a/browser/src/control/Control.StatusBar.js b/browser/src/control/Control.StatusBar.js
index 0bc80485b28fd..00d273a074edf 100644
--- a/browser/src/control/Control.StatusBar.js
+++ b/browser/src/control/Control.StatusBar.js
@@ -181,11 +181,11 @@ class StatusBar extends JSDialog.Toolbar {
 		this.updateHtmlItem('ShowComments', state ? statemsg : ' ');
 	}
 
-	_generateHtmlItem(id) {
+	_generateHtmlItem(id, dataPriority) {
 		var isReadOnlyMode = app.map ? app.map.isReadOnlyMode() : true;
 		var canUserWrite = !app.isReadOnly();
 
-		return {
+		const item = {
 			type: 'container',
 			id: id + '-container',
 			children: [
@@ -194,7 +194,13 @@ class StatusBar extends JSDialog.Toolbar {
 			],
 			vertical: false,
 			visible: false
-		};
+		}
+
+		if (dataPriority) {
+			item.dataPriority = dataPriority;
+		}
+
+		return item;
 	}
 
 	_generateStateMenuEntry(id, text, selection) {
@@ -216,7 +222,7 @@ class StatusBar extends JSDialog.Toolbar {
 			.filter((item) => { return item.selected; })
 			.map((item) => { return item.text; });
 		var text = selected.length ? selected.join('; ') : _('None');
-		return {type: 'menubutton', id: 'StateTableCellMenu', text: text, image: false, menu: submenu, visible: visible};
+		return {type: 'menubutton', id: 'StateTableCellMenu', text: text, image: false, menu: submenu, visible: visible, dataPriority: 5};
 	}
 
 	_generateZoomItems() {
@@ -248,30 +254,30 @@ class StatusBar extends JSDialog.Toolbar {
 			{type: 'customtoolitem',  id: 'searchprev', command: 'searchprev', text: _UNO('.uno:UpSearch'), enabled: false, pressAndHold: true},
 			{type: 'customtoolitem',  id: 'searchnext', command: 'searchnext', text: _UNO('.uno:DownSearch'), enabled: false, pressAndHold: true},
 			{type: 'customtoolitem',  id: 'cancelsearch', command: 'cancelsearch', text: _('Cancel the search'), visible: false},
-			{type: 'separator', id: 'searchbreak', orientation: 'vertical' },
+			{type: 'separator', id: 'searchbreak', orientation: 'vertical'},
 			this._generateHtmlItem('statusdocpos'), 					// spreadsheet
-			this._generateHtmlItem('rowcolselcount'), 					// spreadsheet
+			this._generateHtmlItem('rowcolselcount', 1), 					// spreadsheet
 			this._generateHtmlItem('statepagenumber'), 					// text
-			this._generateHtmlItem('statewordcount'), 					// text
-			this._generateHtmlItem('insertmode'),						// spreadsheet, text
-			this._generateHtmlItem('showcomments'),					    // text
-			this._generateHtmlItem('statusselectionmode'),				// text
+			this._generateHtmlItem('statewordcount', 1), 					// text
+			this._generateHtmlItem('insertmode', 5),						// spreadsheet, text
+			this._generateHtmlItem('showcomments', 4),					    // text
+			this._generateHtmlItem('statusselectionmode', 6),				// text
 			this._generateHtmlItem('slidestatus'),						// presentation
 			this._generateHtmlItem('pagestatus'),						// drawing
-			{type: 'menubutton', id: 'languagestatus:LanguageStatusMenu'},	// spreadsheet, text, presentation
-			{type: 'separator', id: 'languagestatusbreak', orientation: 'vertical', visible: false}, // spreadsheet
-			this._generateHtmlItem('statetablecell'),					// spreadsheet
+			{type: 'menubutton', id: 'languagestatus:LanguageStatusMenu', dataPriority: 3},	// spreadsheet, text, presentation
+			{type: 'separator', id: 'languagestatusbreak', orientation: 'vertical', visible: false, dataPriority: 3}, // spreadsheet
+			this._generateHtmlItem('statetablecell', 4),					// spreadsheet
 			this._generateStateTableCellMenuItem(2, false),			// spreadsheet
-			{type: 'separator', id: 'statetablebreak', orientation: 'vertical', visible: false}, // spreadsheet
+			{type: 'separator', id: 'statetablebreak', orientation: 'vertical', visible: false, dataPriority: 7}, // spreadsheet
 			this._generateHtmlItem('permissionmode'),					// spreadsheet, text, presentation
 			{type: 'toolitem', id: 'signstatus', command: '.uno:Signature', w2icon: '', text: _UNO('.uno:Signature'), visible: false},
 			{type: 'spacer',  id: 'permissionspacer'},
-			this._generateHtmlItem('documentstatus'),					// spreadsheet, text, presentation, drawing
-			{type: 'customtoolitem',  id: 'prev', command: 'prev', text: _UNO('.uno:PageUp', 'text'), pressAndHold: true},
-			{type: 'customtoolitem',  id: 'next', command: 'next', text: _UNO('.uno:PageDown', 'text'), pressAndHold: true},
-			{type: 'separator', id: 'prevnextbreak', orientation: 'vertical'},
+			this._generateHtmlItem('documentstatus', 2),					// spreadsheet, text, presentation, drawing
+			{type: 'customtoolitem',  id: 'prev', command: 'prev', text: _UNO('.uno:PageUp', 'text'), pressAndHold: true, dataPriority: 9},
+			{type: 'customtoolitem',  id: 'next', command: 'next', text: _UNO('.uno:PageDown', 'text'), pressAndHold: true, dataPriority: 9},
+			{type: 'separator', id: 'prevnextbreak', orientation: 'vertical', dataPriority: 9},
 		].concat(window.mode.isTablet() ? [] : [
-			{type: 'customtoolitem',  id: 'zoomreset', command: 'zoomreset', text: _('Reset zoom'), icon: 'zoomreset.svg'},
+			{type: 'customtoolitem',  id: 'zoomreset', command: 'zoomreset', text: _('Reset zoom'), icon: 'zoomreset.svg', dataPriority: 8},
 			{type: 'customtoolitem',  id: 'zoomout', command: 'zoomout', text: _UNO('.uno:ZoomMinus'), icon: 'minus.svg'},
 			{type: 'menubutton', id: 'zoom', text: '100', selected: 'zoom100', menu: this._generateZoomItems(), image: false},
 			{type: 'customtoolitem',  id: 'zoomin', command: 'zoomin', text: _UNO('.uno:ZoomPlus'), icon: 'plus.svg'}
@@ -284,9 +290,8 @@ class StatusBar extends JSDialog.Toolbar {
 
 		this.parentContainer.replaceChildren();
 		this.builder.build(this.parentContainer, this.getToolItems());
-
 		this.onLanguagesUpdated();
-		JSDialog.MakeScrollable(this.parentContainer, this.parentContainer.querySelector('div'));
+		JSDialog.MakeStatusPriority(this.parentContainer.querySelector('div'), this.getToolItems());
 		JSDialog.RefreshScrollables();
 	}
 
@@ -566,6 +571,16 @@ class StatusBar extends JSDialog.Toolbar {
 		JSDialog.MenuDefinitions.set('LanguageStatusMenu', menuEntries);
 	}
 
+    updateDefaultStateAttribute() {
+        const docstatcontainer = document.getElementById('documentstatus-container');
+        const documentStatus = document.getElementById('DocumentStatus');
+        if (documentStatus && (!documentStatus.textContent || documentStatus.textContent.trim() === '')) {
+            docstatcontainer.setAttribute('default-state', 'true');
+        } else if (docstatcontainer.hasAttribute('default-state')) {
+            docstatcontainer.removeAttribute('default-state');
+        }
+    }
+
 	onInitModificationIndicator(lastmodtime) {
 		if (!this.isSaveIndicatorActive())
 			return;
@@ -578,6 +593,7 @@ class StatusBar extends JSDialog.Toolbar {
 			return;
 		}
 		docstatcontainer.classList.remove('hidden');
+        this.updateDefaultStateAttribute()
 
 		this.map.fire('modificationindicatorinitialized');
 	}
@@ -590,6 +606,9 @@ class StatusBar extends JSDialog.Toolbar {
 		if (this._lastModstatus !== e.status) {
 			this.updateHtmlItem('DocumentStatus', e.status);
 			this._lastModStatus = e.status;
+
+            // Update default-state attribute after updating status
+            this.updateDefaultStateAttribute()
 		}
 		if (e.lastSaved !== null && e.lastSaved !== undefined) {
 			const lastSaved = document.getElementById('last-saved');
diff --git a/browser/src/control/jsdialog/Util.ScrollableBar.ts b/browser/src/control/jsdialog/Util.ScrollableBar.ts
index 807a035fb4d44..90941e046edc9 100644
--- a/browser/src/control/jsdialog/Util.ScrollableBar.ts
+++ b/browser/src/control/jsdialog/Util.ScrollableBar.ts
@@ -96,12 +96,92 @@ function setupResizeHandler(container: Element, scrollable: Element) {
 	scrollable.addEventListener('wheel', shiftHandler);
 }
 
+function setupPriorityStatusHandler(scrollable: Element, toolItems: any[]) {
+	const handler = function () {
+		const rootContainer = scrollable.querySelector('div');
+		if (!rootContainer) return;
+
+		const statusBarItems = Array.from(rootContainer.children) as HTMLElement[];
+		// Match DOM items to toolItems by ID and set data-priority
+		statusBarItems.forEach((domItem) => {
+			const toolItem = toolItems.find((item) => {
+				const itemIdBase = item.id.split(':')[0]; // The base ID with a possible suffix for example 'languagestatus:LanguageStatusMenu'
+				return (
+					itemIdBase === domItem.id || item.id + '-container' === domItem.id
+				);
+			});
+
+			if (toolItem && toolItem.dataPriority) {
+				domItem.setAttribute('data-priority', toolItem.dataPriority);
+			} else {
+				domItem.removeAttribute('data-priority');
+			}
+		});
+
+		// Reset visibility of hidden statuses
+		statusBarItems.forEach((item) => {
+			item.classList.remove('status-hidden');
+		});
+
+		const availableWidth = window.innerWidth;
+		let contentWidth = rootContainer.scrollWidth;
+
+		if (contentWidth > availableWidth) {
+			// Group items by data-priority
+			const itemsByPriorityLevel: { [key: string]: HTMLElement[] } = {};
+			statusBarItems.forEach((item) => {
+				if (item.hasAttribute('data-priority')) {
+					const priority = item.getAttribute('data-priority') || '0';
+					if (!itemsByPriorityLevel[priority]) {
+						itemsByPriorityLevel[priority] = [];
+					}
+					itemsByPriorityLevel[priority].push(item);
+				}
+			});
+
+			const priorityLevels = Object.keys(itemsByPriorityLevel)
+				.map(Number)
+				.sort((a, b) => b - a);
+
+			let remainingWidthToFit = contentWidth - availableWidth;
+			// Hide items with the same priority level
+			for (const priority of priorityLevels) {
+				const itemsAtPriority = itemsByPriorityLevel[priority];
+				if (!itemsAtPriority) continue;
+
+				// Calculate total width of the items
+				const combinedWidthAtPriority = itemsAtPriority.reduce(
+					(sum, item) => sum + item.offsetWidth,
+					0,
+				);
+
+				if (remainingWidthToFit > 0) {
+					itemsAtPriority.forEach((item) => {
+						item.classList.add('status-hidden');
+					});
+					remainingWidthToFit -= combinedWidthAtPriority;
+					contentWidth -= combinedWidthAtPriority;
+				} else {
+					break;
+				}
+			}
+		}
+	}.bind(this);
+
+	window.addEventListener('resize', handler);
+}
+
 JSDialog.MakeScrollable = function (parent: Element, scrollable: Element) {
 	L.DomUtil.addClass(scrollable, 'ui-scrollable-content');
 	createScrollButtons(parent, scrollable);
 	setupResizeHandler(parent, scrollable);
 };
 
+JSDialog.MakeStatusPriority = function (scrollable: Element, toolItems: any[]) {
+	L.DomUtil.addClass(scrollable, 'ui-scrollable-content');
+	setupPriorityStatusHandler(scrollable, toolItems);
+};
+
 JSDialog.RefreshScrollables = function () {
 	window.dispatchEvent(new Event('resize'));
 };
diff --git a/cypress_test/integration_tests/common/desktop_helper.js b/cypress_test/integration_tests/common/desktop_helper.js
index 8a491786fe447..997ab1710dc87 100644
--- a/cypress_test/integration_tests/common/desktop_helper.js
+++ b/cypress_test/integration_tests/common/desktop_helper.js
@@ -181,23 +181,7 @@ function shouldHaveZoomLevel(zoomLevel) {
 function makeZoomItemsVisible() {
 	cy.log('>> makeZoomItemsVisible - start');
 
-	const scrollRight = () => {
-		cy.cGet('#toolbar-down .ui-scroll-right:visible').then($scrollRightButton => {
-			if ($scrollRightButton.is(':visible')) {
-				// Wrap .ui-scroll-right so we can continue executing commands
-				cy.wrap($scrollRightButton).click();
-				// Wait the same ms as in Util.ScrollableBar.ts timeout
-				cy.wait(350);
-				// Scroll again if $scrollRightButton is visible
-				cy.cGet('#toolbar-down .ui-scroll-right').then($scrollRightButtonInner => {
-					if ($scrollRightButtonInner.is(':visible'))
-						scrollRight();
-				});
-			}
-		});
-	};
-
-	scrollRight();
+	// Ensure the #zoomin element is visible
 	cy.cGet('#toolbar-down #zoomin').should('be.visible');
 
 	cy.log('<< makeZoomItemsVisible - end');
diff --git a/cypress_test/integration_tests/desktop/calc/bottom_bar_spec.js b/cypress_test/integration_tests/desktop/calc/bottom_bar_spec.js
index b2d5d6b37fcf7..1d38a6852fad6 100644
--- a/cypress_test/integration_tests/desktop/calc/bottom_bar_spec.js
+++ b/cypress_test/integration_tests/desktop/calc/bottom_bar_spec.js
@@ -6,14 +6,17 @@ var calcHelper = require('../../common/calc_helper');
 describe(['tagdesktop', 'tagnextcloud', 'tagproxy'], 'Calc bottom bar tests.', function() {
 
 	beforeEach(function() {
+		// Ensure the viewport is large enough to show the whole status bar
+		// In Calc #StateTableCellMenu has a high data-priority
+		// and will be hidden if the bottom bar doesn't have enough space
+		cy.viewport(1280, 720);
 		helper.setupAndLoadDocument('calc/BottomBar.ods');
 	});
 
 	it('Bottom tool bar.', function() {
 		cy.cGet('#map').focus();
 		calcHelper.clickOnFirstCell();
-		cy.cGet('#StateTableCellMenu').click();
-		// If it clicks, it passes.
+		cy.cGet('#StateTableCellMenu:visible').click();
 		cy.cGet('body').contains('.ui-combobox-entry', 'CountA').click();
 	});
 });
diff --git a/cypress_test/integration_tests/desktop/calc/statusbar_spec.js b/cypress_test/integration_tests/desktop/calc/statusbar_spec.js
index e4d5a865b0d8d..fd5383c5a43aa 100644
--- a/cypress_test/integration_tests/desktop/calc/statusbar_spec.js
+++ b/cypress_test/integration_tests/desktop/calc/statusbar_spec.js
@@ -44,6 +44,10 @@ describe(['tagdesktop', 'tagnextcloud', 'tagproxy'], 'Statubar tests.', function
 	});
 
 	it('Selected data summary.', function() {
+		// Ensure the viewport is large enough to show the whole status bar
+		// In Calc #StateTableCellMenu has a high data-priority
+		// and will be hidden if the status bar doesn't have enough space
+		cy.viewport(1280, 720);
 		cy.cGet('#StateTableCell').should('have.text', 'Average: ; Sum: 0');
 		helper.typeIntoInputField(helper.addressInputSelector, 'A1:A2');
 		cy.cGet('#StateTableCell').should('have.text', 'Average: 15.5; Sum: 31');


Reviews:
user: login: pedropintosilva
body: Thanks @banobe for removing the right and left arrows and updating the cypress.

For this PR to be ready we need to address the following

>     * Make the status bar never need to scroll. Reason: Status bar is not like top toolbar with a series of buttons it's rather a discreet bottom bar that should show the most important status without additional clicks
>       
>       * The available controls on the edges should be always visible
 >       * Remove the scroll indicators
>       * Statuses in the middle get hidden depending on the window's width
>         
>         * We need to make sure that we agree on a priority, if the elements are already positioned correctly (left most import) we don't need to do extra work, we simply hide it from right to left.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T08:42:21Z
user: login: pedropintosilva
body: It looks awesome! However I feel that we cannot hide the search in any case because otherwise the ctrl + F will do nothing,. Furthermore the non-power user will probably seek that search at the bottom (as it is one of the few things that are interactive in the status bar).

* On the left: both search (reasons above) and page number should never disappear (as the user relies on that to know where is at)
  * additionally the search input field has a static width of 200px that should decrease at least to half instead of disappearing completely 
* I like that if in read-only mode that status never disappears, good choice :+1: 
* Also, I noticed that it seems some of the elements (jsdialog menubutton in the status bar) are inheriting some odd font-size which is different that the rest
  * we would probably benefit from using the existing css var --default-font-size
* And please fix the cypress spec
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:28:40Z
user: login: pedropintosilva
body: - [x] On the left: both search (reasons above) and page number should never disappear (as the user relies on that to know where is at)
- [x] the search input field has a static width of 200px that should decrease at least to half instead of disappearing completely
- [x] Read-only mode status should never disappear when on read-only mode
- Also, I noticed that it seems some of the elements (jsdialog menubutton in the status bar) are inheriting some odd font-size which is different that the rest
  - [x] we would probably benefit from using the existing css var --default-font-size
- Please fix cypress spec
  - [x] Removed the scroll test
  - Does it fail for you locally?

state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T15:13:47Z
user: login: pedropintosilva
body: cypress tests need update, for example:

```javascript
 cy:command ✔  cGet	#StateTableCellMenu .arrowbackground
      cy:command ✘  click	
      cy:command ✔  fail:	
                    Test failed: integration_tests/desktop/calc/statusbar_spec.js / Statubar tests. / Selected data summary.
                    
                    Timed out retrying after 10050ms: `cy.click()` failed because this element is not visible:
                    
                    `<div class="arrowbackground">...</div>`
                    
                    This element `<div.arrowbackground>` is not visible because its parent `<div#StateTableCellMenu.unotoolbutton.jsdialog.ui-content.unospan-StateTableCellMenu.StateTableCellMenu.has-label.has-dropdown.menubutton.status-hidden>` has CSS property: `display: none`
```
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T15:18:14Z
user: login: pedropintosilva
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T10:58:33Z
user: login: eszkadev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T10:05:19Z
user: login: eszkadev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T10:06:28Z
user: login: eszkadev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T10:09:50Z
user: login: eszkadev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T10:10:08Z
user: login: eszkadev
body: would be nice to address things I pointed to make it more stable for CI and less  error prone
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T10:11:20Z
user: login: eszkadev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-31T08:57:03Z
user: login: eszkadev
body: code looks fine now
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-31T09:42:32Z

Review comments:
diff_hunk: @@ -194,7 +194,13 @@ class StatusBar extends JSDialog.Toolbar {
 			],
 			vertical: false,
 			visible: false
-		};
+		}
+
+		if (dataPriority) {
+			item['data-priority'] = dataPriority;
path: browser/src/control/Control.StatusBar.js
user: login: eszkadev
body: can we avoid `-` ? (camelCase instead)
It will be less problematic later, eg when using as `item.dataPriority`
created_at: 2025-03-28T10:05:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -216,7 +222,7 @@ class StatusBar extends JSDialog.Toolbar {
 			.filter((item) => { return item.selected; })
 			.map((item) => { return item.text; });
 		var text = selected.length ? selected.join('; ') : _('None');
-		return {type: 'menubutton', id: 'StateTableCellMenu', text: text, image: false, menu: submenu, visible: visible};
+		return {type: 'menubutton', id: 'StateTableCellMenu', text: text, image: false, menu: submenu, visible: visible, 'data-priority': '5'};
path: browser/src/control/Control.StatusBar.js
user: login: eszkadev
body: `dataPriority: 5` would be nicer. 5 should be a number
created_at: 2025-03-28T10:06:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -12,8 +12,14 @@ describe(['tagdesktop', 'tagnextcloud', 'tagproxy'], 'Calc bottom bar tests.', f
 	it('Bottom tool bar.', function() {
 		cy.cGet('#map').focus();
 		calcHelper.clickOnFirstCell();
-		cy.cGet('#StateTableCellMenu').click();
-		// If it clicks, it passes.
-		cy.cGet('body').contains('.ui-combobox-entry', 'CountA').click();
+		cy.cGet('#StateTableCellMenu').then(($tableCellMenu) => {
+			if ($tableCellMenu.is(':visible')) {
path: cypress_test/integration_tests/desktop/calc/bottom_bar_spec.js
user: login: eszkadev
body: Please avoid conditional checks in cypress, it makes it unstable.
Please to explicit checks for visible element and explicit check if something is hidden or missing.
`cy.cGet('#StateTableCellMenu:visible').click();` <- does what that code does. If it will fail - cypress will print that it was invisible.

We want strict checks, which can be repeated automatically.
created_at: 2025-03-28T10:09:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -51,10 +51,16 @@ describe(['tagdesktop', 'tagnextcloud', 'tagproxy'], 'Statubar tests.', function
 		cy.cGet('#StateTableCell').should('have.text', 'Average: 10; Sum: 10');
 
 		desktopHelper.makeZoomItemsVisible();
-		cy.cGet('#StateTableCellMenu .unolabel').contains('Average; Sum');
-		cy.cGet('#StateTableCellMenu .arrowbackground').click();
-		cy.cGet('.jsdialog-overlay').should('exist');
-		cy.cGet('.ui-combobox-entry.selected').contains(/Average|Sum/g);
+		cy.cGet('#StateTableCellMenu').then(($tableCellMenu) => {
+			if ($tableCellMenu.is(':visible')) {
path: cypress_test/integration_tests/desktop/calc/statusbar_spec.js
user: login: eszkadev
body: no conditional checks
created_at: 2025-03-28T10:10:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2024,6 +2024,11 @@ input[type='number']:hover::-webkit-outer-spin-button {
 	background-color: transparent !important;
 	border-color: transparent;
 }
+
+#toolbar-down  .jsdialog .ui-edit-container{
+	place-content: center;
path: browser/css/jsdialogs.css
user: login: eszkadev
body: possibly that should be the default for any `.ui-edit-container`, but for now is fine
created_at: 2025-03-31T08:57:03Z
author_association: CONTRIBUTOR

PR comments:
user: login: eszkadev
created_at: 2025-03-19T07:25:39Z
body: I'm not sure about it. Maybe we should improve detection of case when to hide the arrows?
With the patch in the small windows user cannot access zooming without touch screen.
(it requires shift and scroll wheel - not known by many people)

[resize-2025-03-19_08.23.42.webm](https://github.com/user-attachments/assets/054f99af-50fd-4434-8f71-9ea3e41177db)

author_association: CONTRIBUTOR
user: login: eszkadev
created_at: 2025-03-19T07:26:12Z
body: BTW also search bar seems to be misaligned now
author_association: CONTRIBUTOR
user: login: banobepascal
created_at: 2025-03-19T15:53:46Z
body: > I'm not sure about it. Maybe we should improve detection of case when to hide the arrows? With the patch in the small windows user cannot access zooming without touch screen. (it requires shift and scroll wheel - not known by many people)
> 
>  resize-2025-03-19_08.23.42.webm

I think  when the window becomes smaller we need to hide some information that might not be so crucial to the user or come up with a different implementation to show the information and with this implementation, we shall not need to scroll the status bar and also the arrows will not be needed. 

author_association: CONTRIBUTOR
user: login: pedropintosilva
created_at: 2025-03-19T16:22:13Z
body: now testing, I think I wrote somewhere in an issue and to Banobe. But let me write it here, the goal is:

* Make the status bar never need to scroll. Reason: Status bar is not like top toolbar with a series of buttons it's rather a discreet bottom bar that should show the most important status without additional clicks
  * The available controls on the edges should be always visible
  * Remove the scroll indicators
  * Statuses in the middle get hidden depending on the window's width
    * We need to make sure that we agree on a priority, if the elements are already positioned correctly (left most import) we don't need to do extra work, we simply hide it from right to left.
* Follow up enhancements
  * Add button that appears when there are hidden status. That button triggers a new menu widget that shows all those status.
author_association: CONTRIBUTOR
user: login: eszkadev
created_at: 2025-03-20T08:51:10Z
body: @pedropintosilva I see, then I'm good with the change.

For priority: possibly we want new property for a toolbar item in the JSON.
No priority - show always.
Priority - number

We did "make scrollable" in the past. There is logic for overflow detection. We can reuse it.
In that case we should do similar thing: hide lowest priority, check overflow, until no-overflow or no more prioritized widgets.

So this way there is no hardcoded id needed :)
author_association: CONTRIBUTOR
user: login: banobepascal
created_at: 2025-03-25T14:42:40Z
body: @pedropintosilva @eszkadev please review
author_association: CONTRIBUTOR