diff --git a/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt b/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt
index d78a4228f9..c82d96fa95 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt
@@ -616,7 +616,7 @@
});
// move filter into action header
- $("#type_filter_container").detach().prependTo('#grid-aliases-header > .row > .actionBar > .actions');
+ $("#type_filter_container").detach().insertAfter('#grid-aliases-header .search');
// alias size in service container
$("#aliases_stat").detach().prependTo('#service_status_container');
$("#service_status_container").css('width', '250px');
diff --git a/src/opnsense/mvc/app/views/OPNsense/Firewall/filter.volt b/src/opnsense/mvc/app/views/OPNsense/Firewall/filter.volt
index e23e3388a7..a7a6721e77 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Firewall/filter.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Firewall/filter.volt
@@ -58,7 +58,7 @@
$("#reconfigureAct").SimpleActionButton();
// move filter into action header
- $("#type_filter_container").detach().prependTo('#grid-rules-header > .row > .actionBar > .actions');
+ $("#type_filter_container").detach().insertAfter('#grid-rules-header .search');
$("#category_filter").change(function(){
$('#grid-rules').bootgrid('reload');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/Firewall/filter_rule.volt b/src/opnsense/mvc/app/views/OPNsense/Firewall/filter_rule.volt
index 3528893589..091ae9ce9b 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Firewall/filter_rule.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Firewall/filter_rule.volt
@@ -736,7 +736,7 @@
$("#interface_select_container").show();
// move selectpickers into action bar
- $("#interface_select_container").detach().insertBefore('#{{formGridFilterRule["table_id"]}}-header > .row > .actionBar > .search');
+ $("#interface_select_container").detach().insertBefore('#{{formGridFilterRule["table_id"]}}-header .search');
$('#interface_select').on('changed.bs.select', function () {
// Skip grid reload during reconfigureAct and initial page load
if (!interfaceInitialized || reconfigureActInProgress) return;
@@ -978,6 +978,41 @@
opacity: 0.4;
}
+ /* Action bar specific layout */
+ #interface_select_container,
+ #type_filter_container {
+ float: none !important;
+ flex: 1 1 150px;
+ min-width: 0;
+ max-width: 400px;
+ }
+
+ #interface_select_container .bootstrap-select,
+ #type_filter_container .bootstrap-select {
+ flex: 1 1 auto;
+ min-width: 0;
+ }
+
+ .bootgrid-header .actionBar .btn-group {
+ align-items: flex-start;
+ }
+
+ @media (max-width: 1024px) {
+ #interface_select_container,
+ #type_filter_container {
+ flex: 1 1 100%;
+ max-width: 100%;
+ margin: 0;
+ }
+
+ #dialogFilterRule-header #inspect_toggle_container,
+ #dialogFilterRule-header #tree_toggle_container,
+ #dialogFilterRule-header #tree_expand_container {
+ flex: 1 1 0;
+ margin: 0;
+ }
+ }
+
.stats-cell {
display: flex;
flex-direction: column;
@@ -993,11 +1028,11 @@
-
-
+
diff --git a/src/opnsense/mvc/app/views/OPNsense/IPsec/leases.volt b/src/opnsense/mvc/app/views/OPNsense/IPsec/leases.volt
index f7c25c7320..a90cb7a542 100644
--- a/src/opnsense/mvc/app/views/OPNsense/IPsec/leases.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/IPsec/leases.volt
@@ -55,7 +55,7 @@
}
}
});
- $("#pool_filter_container").detach().prependTo('#grid-leases-header > .row > .actionBar > .actions');
+ $("#pool_filter_container").detach().insertAfter('#grid-leases-header .search');
$("#pool_filter").change(function(){
$('#grid-leases').bootgrid('reload');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/Interface/vip.volt b/src/opnsense/mvc/app/views/OPNsense/Interface/vip.volt
index 7a2dcce5ab..88cb6b0e34 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Interface/vip.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Interface/vip.volt
@@ -77,7 +77,8 @@
)
);
- $("#mode_filter_container").detach().prependTo('#{{formGridVip["table_id"]}}-header > .row > .actionBar > .actions');
+ $("#mode_filter_container").detach().insertAfter('#{{formGridVip["table_id"]}}-header .search');
+
/**
* select an unassigned carp vhid
*/
diff --git a/src/opnsense/mvc/app/views/OPNsense/Kea/leases4.volt b/src/opnsense/mvc/app/views/OPNsense/Kea/leases4.volt
index 2439b59d1a..390e610f51 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Kea/leases4.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Kea/leases4.volt
@@ -77,7 +77,7 @@
}
});
- $("#interface-selection-wrapper").detach().prependTo('#grid-leases-header > .row > .actionBar > .actions');
+ $("#interface-selection-wrapper").detach().insertAfter('#grid-leases-header .search');
updateServiceControlUI('kea');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/Kea/leases6.volt b/src/opnsense/mvc/app/views/OPNsense/Kea/leases6.volt
index cdac418cce..c62f5cde15 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Kea/leases6.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Kea/leases6.volt
@@ -77,7 +77,7 @@
}
});
- $("#interface-selection-wrapper").detach().prependTo('#grid-leases-header > .row > .actionBar > .actions');
+ $("#interface-selection-wrapper").detach().insertAfter('#grid-leases-header .search');
updateServiceControlUI('kea');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/OpenVPN/status.volt b/src/opnsense/mvc/app/views/OPNsense/OpenVPN/status.volt
index 247ed4f0b9..3b98ffe666 100644
--- a/src/opnsense/mvc/app/views/OPNsense/OpenVPN/status.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/OpenVPN/status.volt
@@ -101,7 +101,7 @@
$('#grid-sessions').bootgrid('reload');
});
- $("#type_filter_container").detach().prependTo('#grid-sessions-header > .row > .actionBar > .actions');
+ $("#type_filter_container").detach().insertAfter('#grid-sessions-header .search');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/Trust/cert.volt b/src/opnsense/mvc/app/views/OPNsense/Trust/cert.volt
index 7002b6df18..86c67cfb85 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Trust/cert.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Trust/cert.volt
@@ -212,7 +212,7 @@
}
});
- $("#filter_container").detach().prependTo('#{{formGridCert['table_id']}}-header > .row > .actionBar > .actions');
+ $("#filter_container").detach().insertAfter('#{{formGridCert['table_id']}}-header .search');
$(".cert_filter").change(function(){
$("#{{formGridCert['table_id']}}").bootgrid('reload');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/Wireguard/diagnostics.volt b/src/opnsense/mvc/app/views/OPNsense/Wireguard/diagnostics.volt
index 35e885e937..e3f2f08018 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Wireguard/diagnostics.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Wireguard/diagnostics.volt
@@ -89,7 +89,7 @@
$('[data-toggle="tooltip"]').tooltip();
});
- $("#type_filter_container").detach().prependTo('#grid-sessions-header > .row > .actionBar > .actions');
+ $("#type_filter_container").detach().insertAfter('#grid-sessions-header .search');
});
diff --git a/src/opnsense/mvc/app/views/OPNsense/Wireguard/general.volt b/src/opnsense/mvc/app/views/OPNsense/Wireguard/general.volt
index e2bfbff564..41cf975f57 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Wireguard/general.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Wireguard/general.volt
@@ -108,7 +108,7 @@
/**
* Quick instance filter on top
*/
- $("#filter_container").detach().prependTo('#{{formGridWireguardClient["table_id"]}}-header > .row > .actionBar > .actions');
+ $("#filter_container").detach().insertAfter('#{{formGridWireguardClient["table_id"]}}-header .search');
$("#server_filter").change(function(){
$('#{{formGridWireguardClient['table_id']}}').bootgrid('reload');
});
diff --git a/src/opnsense/www/css/opnsense-bootgrid-layout.css b/src/opnsense/www/css/opnsense-bootgrid-layout.css
new file mode 100644
index 0000000000..ebbc655ee5
--- /dev/null
+++ b/src/opnsense/www/css/opnsense-bootgrid-layout.css
@@ -0,0 +1,76 @@
+/*
+ * For universal layout adjustments that do not need theme compilation.
+ * No color or other variables allowed, only static layout changes.
+ * Avoids having to recompile/fix themes.
+ * /
+
+/* Action Bar responsive style */
+.bootgrid-header .actionBar {
+ display: flex;
+ flex-wrap: nowrap;
+ gap: 8px;
+ min-width: 0;
+}
+
+.bootgrid-header .actionBar > .search {
+ margin-left: auto;
+ padding-left: 20px;
+ flex: 0 1 400px;
+ min-width: 100px;
+}
+
+.bootgrid-header .actionBar > .btn-group,
+.bootgrid-header .actionBar > .actions .btn-group {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+@media (max-width: 1024px) {
+ .bootgrid-header .actionBar {
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ align-items: stretch;
+ max-width: 100%;
+ }
+
+ .bootgrid-header .actionBar > * {
+ flex: 1 1 100%;
+ margin: 0;
+ float: none;
+ display: flex;
+ }
+
+ .bootgrid-header .actionBar .bootstrap-select,
+ .bootgrid-header .actionBar .bootstrap-select > .dropdown-toggle,
+ .bootgrid-header .actionBar .btn,
+ .bootgrid-header .actionBar .search .input-group,
+ .bootgrid-header .actionBar .search .form-control {
+ flex: 1;
+ width: 100%;
+ max-width: 100%;
+ }
+
+ .bootgrid-header .actionBar .search {
+ flex: 1 1 100%;
+ margin: 0;
+ padding-left: 0;
+ }
+
+ .bootgrid-header .actionBar .search .input-group {
+ margin: 0;
+ }
+
+ .bootgrid-header .actionBar .actions,
+ .bootgrid-header .actionBar .actions-group {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ gap: 8px;
+ flex: 1 1 100%;
+ }
+
+ .bootgrid-header .actionBar .actions > *,
+ .bootgrid-header .actionBar .actions-group > * {
+ flex: 1;
+ }
+}
diff --git a/src/opnsense/www/js/opnsense_bootgrid.js b/src/opnsense/www/js/opnsense_bootgrid.js
index 617efbb448..e55ffaf753 100644
--- a/src/opnsense/www/js/opnsense_bootgrid.js
+++ b/src/opnsense/www/js/opnsense_bootgrid.js
@@ -486,6 +486,8 @@ class UIBootgrid {
visible: data.visible ?? true,
sequence: data.sequence ?? null,
width: val.width,
+ minWidth: data.minWidth || 80,
+ maxWidth: data.maxWidth ?? null,
editable: false,
sortable: data.sortable ?? true
}
@@ -564,6 +566,13 @@ class UIBootgrid {
col['maxWidth'] = field.width;
} else if (field.width) {
col['width'] = field.width;
+ } else {
+ if (field.minWidth) {
+ col['minWidth'] = field.minWidth;
+ }
+ if (field.maxWidth) {
+ col['maxWidth'] = field.maxWidth;
+ }
}
result.push(col);