feat: Hide omnibox and apps menu based on product configuration

- Hide omnibox search mechanism when search_enabled=false in product config
- Hide apps menu launcher when menu_launcher_enabled=false or when no apps are visible
- Check effectiveApps (after filtering by compiled features) to determine if menu should be shown
- Automatically hide the apps menu button when there are no apps to display

This provides UI controls that respect the new search_enabled and menu_launcher_enabled
directives added to the .product configuration.
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-01-29 23:56:00 -03:00
parent 27e839f22a
commit 34d55825bc

View file

@ -47,12 +47,15 @@ function applyProductConfig(config) {
// Check if we have compiled_features info to filter even further // Check if we have compiled_features info to filter even further
// This ensures we don't show apps that are enabled in config but not compiled in binary // This ensures we don't show apps that are enabled in config but not compiled in binary
if (config.compiled_features && Array.isArray(config.compiled_features)) { if (config.compiled_features && Array.isArray(config.compiled_features)) {
const compiledSet = new Set(config.compiled_features.map(f => f.toLowerCase())); const compiledSet = new Set(
effectiveApps = effectiveApps.filter(app => config.compiled_features.map((f) => f.toLowerCase()),
compiledSet.has(app.toLowerCase()) || );
app.toLowerCase() === 'settings' || effectiveApps = effectiveApps.filter(
app.toLowerCase() === 'auth' || (app) =>
app.toLowerCase() === 'admin' // Admin usually contains settings which is always there compiledSet.has(app.toLowerCase()) ||
app.toLowerCase() === "settings" ||
app.toLowerCase() === "auth" ||
app.toLowerCase() === "admin", // Admin usually contains settings which is always there
); );
// Also call a helper to hide UI elements for non-compiled features explicitly // Also call a helper to hide UI elements for non-compiled features explicitly
@ -61,6 +64,33 @@ function applyProductConfig(config) {
} }
filterAppsByConfig(effectiveApps); filterAppsByConfig(effectiveApps);
// Check if there are any visible apps after filtering
const hasVisibleApps = effectiveApps.length > 0;
// Hide apps menu button if menu launcher is disabled or if there are no apps to show
if (config.menu_launcher_enabled === false || !hasVisibleApps) {
const appsButton = document.getElementById("appsButton");
if (appsButton) {
appsButton.style.display = "none";
}
const appsMenuContainer = document.querySelector(".apps-menu-container");
if (appsMenuContainer) {
appsMenuContainer.style.display = "none";
}
}
}
// Hide omnibox if search is disabled
if (config.search_enabled === false) {
const omnibox = document.getElementById("omnibox");
if (omnibox) {
omnibox.style.display = "none";
}
const headerCenter = document.querySelector(".header-center");
if (headerCenter) {
headerCenter.style.display = "none";
}
} }
// Apply custom logo // Apply custom logo
@ -95,18 +125,22 @@ function applyProductConfig(config) {
// Hide UI elements that require features not compiled in the binary // Hide UI elements that require features not compiled in the binary
function hideNonCompiledUI(compiledSet) { function hideNonCompiledUI(compiledSet) {
// Hide elements with data-feature attribute that aren't in compiled set // Hide elements with data-feature attribute that aren't in compiled set
document.querySelectorAll('[data-feature]').forEach(el => { document.querySelectorAll("[data-feature]").forEach((el) => {
const feature = el.getAttribute('data-feature').toLowerCase(); const feature = el.getAttribute("data-feature").toLowerCase();
// Allow settings/admin as they are usually core // Allow settings/admin as they are usually core
if (!compiledSet.has(feature) && feature !== 'settings' && feature !== 'admin') { if (
el.style.display = 'none'; !compiledSet.has(feature) &&
el.classList.add('hidden-uncompiled'); feature !== "settings" &&
feature !== "admin"
) {
el.style.display = "none";
el.classList.add("hidden-uncompiled");
} }
}); });
// Also look for specific sections that might map to features // Also look for specific sections that might map to features
// e.g. .feature-mail, .feature-meet classes // e.g. .feature-mail, .feature-meet classes
compiledSet.forEach(feature => { compiledSet.forEach((feature) => {
// This loop defines what IS available. // This loop defines what IS available.
// Logic should be inverse: find all feature- classes and hide if not in set // Logic should be inverse: find all feature- classes and hide if not in set
// But scanning all classes is expensive. // But scanning all classes is expensive.