From 030afb69d12d6d5e41b7da9019a42f540c92865a Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 6 Aug 2026 12:14:38 -0700 Subject: [PATCH 1/6] Admin button that hides the search icon in the SDMS header --- .../labkey/api/search/NoopSearchService.java | 7 +++++ .../org/labkey/api/search/SearchService.java | 3 ++ .../core/view/template/bootstrap/header.jsp | 3 +- .../org/labkey/search/SearchController.java | 31 +++++++++++++++++++ .../search/model/AbstractSearchService.java | 5 +++ .../search/model/SearchPropertyManager.java | 19 +++++++++--- .../search/model/SearchStartupProperties.java | 11 +++++++ .../org/labkey/search/view/indexerAdmin.jsp | 29 +++++++++++++++++ 8 files changed, 102 insertions(+), 6 deletions(-) diff --git a/api/src/org/labkey/api/search/NoopSearchService.java b/api/src/org/labkey/api/search/NoopSearchService.java index 56be54eb815..006cbef00cb 100644 --- a/api/src/org/labkey/api/search/NoopSearchService.java +++ b/api/src/org/labkey/api/search/NoopSearchService.java @@ -365,6 +365,13 @@ public void pauseCrawler() { } + @Override + public boolean isSearchIconVisible() + { + // No persisted setting to consult, so don't be the reason the header hides the icon + return true; + } + @Override public @Nullable Throwable getConfigurationError() { diff --git a/api/src/org/labkey/api/search/SearchService.java b/api/src/org/labkey/api/search/SearchService.java index 0dd6ae0ada7..874b22cbe3f 100644 --- a/api/src/org/labkey/api/search/SearchService.java +++ b/api/src/org/labkey/api/search/SearchService.java @@ -442,6 +442,9 @@ public String normalizeHref(Path contextPath, Container c) void resetIndex(); void startCrawler(); void pauseCrawler(); + + /** @return should the search icon be shown in the page header; controlled from the Full-Text Search admin page */ + boolean isSearchIconVisible(); void updateIndex(String reason); void refreshNow(); diff --git a/core/src/org/labkey/core/view/template/bootstrap/header.jsp b/core/src/org/labkey/core/view/template/bootstrap/header.jsp index 5369a16f4cf..7ac0abc2352 100644 --- a/core/src/org/labkey/core/view/template/bootstrap/header.jsp +++ b/core/src/org/labkey/core/view/template/bootstrap/header.jsp @@ -19,6 +19,7 @@ <%@ page import="org.labkey.api.data.Container" %> <%@ page import="org.labkey.api.module.ModuleLoader" %> <%@ page import="org.labkey.api.portal.ProjectUrls" %> +<%@ page import="org.labkey.api.search.SearchService" %> <%@ page import="org.labkey.api.search.SearchUrls" %> <%@ page import="org.labkey.api.search.SearchUtils" %> <%@ page import="org.labkey.api.security.AuthenticationManager" %> @@ -83,7 +84,7 @@ LookAndFeelProperties laf = LookAndFeelProperties.getInstance(c); ModuleLoader moduleLoader = ModuleLoader.getInstance(); boolean isStartupComplete = moduleLoader.isStartupComplete(); - boolean showSearch = isStartupComplete && PageFlowUtil.urlProviderOptional(SearchUrls.class) != null; + boolean showSearch = isStartupComplete && PageFlowUtil.urlProviderOptional(SearchUrls.class) != null && SearchService.get().isSearchIconVisible(); HtmlView headerHtml = new HeaderProperties(getContainer()).getView(); String siteShortName = (laf.getShortName() != null && !laf.getShortName().isEmpty()) ? laf.getShortName() : null; diff --git a/search/src/org/labkey/search/SearchController.java b/search/src/org/labkey/search/SearchController.java index 0c7d0bb90c2..b27ff270645 100644 --- a/search/src/org/labkey/search/SearchController.java +++ b/search/src/org/labkey/search/SearchController.java @@ -77,6 +77,7 @@ import org.labkey.search.model.CrawlerRunningState; import org.labkey.search.model.IndexInspector; import org.labkey.search.model.LuceneDirectoryType; +import org.labkey.search.model.SearchIconState; import org.labkey.search.model.SearchPropertyManager; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValues; @@ -148,6 +149,8 @@ public static class AdminForm private int msg = 0; private boolean pause; private boolean start; + private boolean hideSearchIcon; + private boolean showSearchIcon; private boolean delete; private String indexPath; @@ -199,6 +202,26 @@ public void setPause(boolean pause) this.pause = pause; } + public boolean isHideSearchIcon() + { + return hideSearchIcon; + } + + public void setHideSearchIcon(boolean hideSearchIcon) + { + this.hideSearchIcon = hideSearchIcon; + } + + public boolean isShowSearchIcon() + { + return showSearchIcon; + } + + public void setShowSearchIcon(boolean showSearchIcon) + { + this.showSearchIcon = showSearchIcon; + } + public String getIndexPath() { return indexPath; @@ -335,6 +358,14 @@ else if (form.isPause()) SearchPropertyManager.setCrawlerRunningState(getUser(), CrawlerRunningState.Pause); ss.pauseCrawler(); } + else if (form.isShowSearchIcon()) + { + SearchPropertyManager.setSearchIconState(getUser(), SearchIconState.Show); + } + else if (form.isHideSearchIcon()) + { + SearchPropertyManager.setSearchIconState(getUser(), SearchIconState.Hide); + } else if (form.isDelete()) { ss.deleteIndex("a site admin requested it"); diff --git a/search/src/org/labkey/search/model/AbstractSearchService.java b/search/src/org/labkey/search/model/AbstractSearchService.java index 9c60beaff2a..55ba30b7354 100644 --- a/search/src/org/labkey/search/model/AbstractSearchService.java +++ b/search/src/org/labkey/search/model/AbstractSearchService.java @@ -963,6 +963,11 @@ public void pauseCrawler() } } + @Override + public boolean isSearchIconVisible() + { + return SearchPropertyManager.getSearchIconState(); + } @Override public void updateIndex(String reason) diff --git a/search/src/org/labkey/search/model/SearchPropertyManager.java b/search/src/org/labkey/search/model/SearchPropertyManager.java index 3c88f75776f..9266ce373c6 100644 --- a/search/src/org/labkey/search/model/SearchPropertyManager.java +++ b/search/src/org/labkey/search/model/SearchPropertyManager.java @@ -30,11 +30,6 @@ import java.io.File; import java.util.Map; -/** - * User: adam - * Date: Apr 20, 2010 - * Time: 7:01:16 PM - */ public class SearchPropertyManager { private static final String CATEGORY = SearchModule.class.getName(); @@ -42,6 +37,7 @@ public class SearchPropertyManager private static final String INDEX_PATH = "primaryIndexPath"; // Note: don't change this legacy name private static final String DIRECTORY_TYPE = "directoryType"; private static final String FILE_SIZE_LIMIT = "fileSizeLimitMB"; + private static final String SEARCH_ICON_STATE = "searchIconState"; public static boolean getCrawlerRunningState() @@ -60,6 +56,19 @@ public static void setCrawlerRunningState(User user, CrawlerRunningState state) audit(user, state.getAuditMessage()); } + /** @return true unless an admin has explicitly hidden the search icon */ + public static boolean getSearchIconState() + { + String state = getProperty(SEARCH_ICON_STATE); + return null == state || "true".equals(state); + } + + public static void setSearchIconState(User user, SearchIconState state) + { + setProperty(SEARCH_ICON_STATE, String.valueOf(state.isVisible())); + audit(user, state.getAuditMessage()); + } + public static String getUnsubstitutedIndexDirectory() { String path = getProperty(INDEX_PATH); diff --git a/search/src/org/labkey/search/model/SearchStartupProperties.java b/search/src/org/labkey/search/model/SearchStartupProperties.java index 92614f8d0d9..85d9b20e673 100644 --- a/search/src/org/labkey/search/model/SearchStartupProperties.java +++ b/search/src/org/labkey/search/model/SearchStartupProperties.java @@ -63,6 +63,17 @@ public void setProperty(@NotNull SearchService ss, SearchIndexStartupHandler ind SearchPropertyManager.setCrawlerRunningState(null, state); } }, + searchIconState("Hide or show the search icon in the page header. Valid values: " + Arrays.toString(SearchIconState.values())){ + @Override + public void setProperty(@NotNull SearchService ss, SearchIndexStartupHandler indexStartupHandler, String value) + { + SearchIconState state = EnumUtils.getEnum(SearchIconState.class, value); + if (null == state) + LOG.error("Unrecognized value for \"searchIconState\": \"{}\"", value); + else + SearchPropertyManager.setSearchIconState(null, state); + } + }, deleteIndex("Delete index and clear last indexed, after setting other properties"){ @Override public void setProperty(@NotNull SearchService ss, SearchIndexStartupHandler indexStartupHandler, String value) diff --git a/search/src/org/labkey/search/view/indexerAdmin.jsp b/search/src/org/labkey/search/view/indexerAdmin.jsp index 8be2e31b722..256e4052baa 100644 --- a/search/src/org/labkey/search/view/indexerAdmin.jsp +++ b/search/src/org/labkey/search/view/indexerAdmin.jsp @@ -127,6 +127,35 @@ else <%= button("Start Crawler").submit(true) %><% } } + %> + +

+ +

+ <% + + if (ss.isSearchIconVisible()) + { + %><% + + if (hasAdminOpsPerms) + { + %> + + <% + } + } + else + { + %><% + + if (hasAdminOpsPerms) + { + %> + + <% + } + } %>
The search icon is shown in the page header.
<%= button("Hide Search Icon").submit(true) %>
The search icon is hidden in the page header.
<%= button("Show Search Icon").submit(true) %>

<% From ddfe58f99b06e5e25c698618cf84985f352169c8 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 6 Aug 2026 13:07:28 -0700 Subject: [PATCH 2/6] Remove unused methods --- .../org/labkey/api/exp/api/ExperimentService.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/api/src/org/labkey/api/exp/api/ExperimentService.java b/api/src/org/labkey/api/exp/api/ExperimentService.java index fd0b9fce06f..259e36f75e6 100644 --- a/api/src/org/labkey/api/exp/api/ExperimentService.java +++ b/api/src/org/labkey/api/exp/api/ExperimentService.java @@ -82,7 +82,6 @@ import org.labkey.api.reader.TabLoader; import org.labkey.api.security.User; import org.labkey.api.services.ServiceRegistry; -import org.labkey.api.util.IntegerUtils; import org.labkey.api.util.Pair; import org.labkey.api.util.StringUtilsLabKey; import org.labkey.api.view.HttpView; @@ -1384,16 +1383,4 @@ public XarImportOptions setStrictValidateExistingSampleType(boolean strictValida return this; } } - - @Deprecated // Use IntegerUtils.asLong() instead - static Long asLong(Object o) - { - return IntegerUtils.asLong(o); - } - - @Deprecated // Use IntegerUtils.asInteger() instead - static Integer asInteger(Object o) - { - return IntegerUtils.asInteger(o); - } } From 7d8a75300a94c4d7976baa1529fb003072b498cf Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 6 Aug 2026 13:08:38 -0700 Subject: [PATCH 3/6] Missed file --- .../labkey/search/model/SearchIconState.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 search/src/org/labkey/search/model/SearchIconState.java diff --git a/search/src/org/labkey/search/model/SearchIconState.java b/search/src/org/labkey/search/model/SearchIconState.java new file mode 100644 index 00000000000..60f66b9907f --- /dev/null +++ b/search/src/org/labkey/search/model/SearchIconState.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.labkey.search.model; + +public enum SearchIconState +{ + Hide + { + @Override + String getAuditMessage() + { + return "Search Icon Hidden"; + } + + @Override + boolean isVisible() + { + return false; + } + }, + Show + { + @Override + String getAuditMessage() + { + return "Search Icon Shown"; + } + + @Override + boolean isVisible() + { + return true; + } + }; + + abstract String getAuditMessage(); + abstract boolean isVisible(); +} From e1d472fa82512db3a8b9dc2f45e5665a25de879b Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 6 Aug 2026 13:09:00 -0700 Subject: [PATCH 4/6] Remove pointless check --- api/src/org/labkey/api/query/UserIdRenderer.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/src/org/labkey/api/query/UserIdRenderer.java b/api/src/org/labkey/api/query/UserIdRenderer.java index f15cc015230..90320f759ff 100644 --- a/api/src/org/labkey/api/query/UserIdRenderer.java +++ b/api/src/org/labkey/api/query/UserIdRenderer.java @@ -78,13 +78,13 @@ public String renderURL(RenderContext ctx) return null; boolean isDeletedUser = UserManager.getUser(displayedUserId) == null; - if (!isDeletedUser && displayedUserId != null) + if (!isDeletedUser) { - ActionURL url = UserManager.getUserDetailsURL(ctx.getContainer(), loggedInUser, displayedUserId); - if (url != null) - { - return url.toString(); - } + ActionURL url = UserManager.getUserDetailsURL(ctx.getContainer(), loggedInUser, displayedUserId); + if (url != null) + { + return url.toString(); + } } return null; From 924047a7329d551aa4836c944add843c4ce38f99 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 6 Aug 2026 13:35:13 -0700 Subject: [PATCH 5/6] Put all the showSearch conditionals in one place --- .../org/labkey/core/view/template/bootstrap/header.jsp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/org/labkey/core/view/template/bootstrap/header.jsp b/core/src/org/labkey/core/view/template/bootstrap/header.jsp index 7ac0abc2352..c43d52c28f5 100644 --- a/core/src/org/labkey/core/view/template/bootstrap/header.jsp +++ b/core/src/org/labkey/core/view/template/bootstrap/header.jsp @@ -84,7 +84,6 @@ LookAndFeelProperties laf = LookAndFeelProperties.getInstance(c); ModuleLoader moduleLoader = ModuleLoader.getInstance(); boolean isStartupComplete = moduleLoader.isStartupComplete(); - boolean showSearch = isStartupComplete && PageFlowUtil.urlProviderOptional(SearchUrls.class) != null && SearchService.get().isSearchIconVisible(); HtmlView headerHtml = new HeaderProperties(getContainer()).getView(); String siteShortName = (laf.getShortName() != null && !laf.getShortName().isEmpty()) ? laf.getShortName() : null; @@ -140,7 +139,12 @@ %>