Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions api/src/org/labkey/api/exp/api/ExperimentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
12 changes: 6 additions & 6 deletions api/src/org/labkey/api/query/UserIdRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions api/src/org/labkey/api/search/NoopSearchService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
3 changes: 3 additions & 0 deletions api/src/org/labkey/api/search/SearchService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
9 changes: 7 additions & 2 deletions core/src/org/labkey/core/view/template/bootstrap/header.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -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" %>
Expand Down Expand Up @@ -83,7 +84,6 @@
LookAndFeelProperties laf = LookAndFeelProperties.getInstance(c);
ModuleLoader moduleLoader = ModuleLoader.getInstance();
boolean isStartupComplete = moduleLoader.isStartupComplete();
boolean showSearch = isStartupComplete && PageFlowUtil.urlProviderOptional(SearchUrls.class) != null;

HtmlView headerHtml = new HeaderProperties(getContainer()).getView();
String siteShortName = (laf.getShortName() != null && !laf.getShortName().isEmpty()) ? laf.getShortName() : null;
Expand Down Expand Up @@ -139,7 +139,12 @@
%>
<ul class="navbar-nav-lk">
<%
if (showSearch && pageConfig.shouldIncludeSearch())
boolean showSearch =
isStartupComplete &&
PageFlowUtil.urlProviderOptional(SearchUrls.class) != null &&
SearchService.get().isSearchIconVisible() &&
pageConfig.shouldIncludeSearch();
if (showSearch)
{
%>
<li class="navbar-search hidden-xs">
Expand Down
31 changes: 31 additions & 0 deletions search/src/org/labkey/search/SearchController.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down
5 changes: 5 additions & 0 deletions search/src/org/labkey/search/model/AbstractSearchService.java
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,11 @@ public void pauseCrawler()
}
}

@Override
public boolean isSearchIconVisible()
{
return SearchPropertyManager.getSearchIconState();
}

@Override
public void updateIndex(String reason)
Expand Down
51 changes: 51 additions & 0 deletions search/src/org/labkey/search/model/SearchIconState.java
Original file line number Diff line number Diff line change
@@ -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();
}
19 changes: 14 additions & 5 deletions search/src/org/labkey/search/model/SearchPropertyManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,14 @@
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();
private static final String CRAWLER_RUNNING_STATE = "runningState";
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()
Expand All @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions search/src/org/labkey/search/model/SearchStartupProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
29 changes: 29 additions & 0 deletions search/src/org/labkey/search/view/indexerAdmin.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,35 @@ else
<tr><td><%= button("Start Crawler").submit(true) %></td></tr><%
}
}
%>
</table>
</labkey:form></p>

<p><labkey:form method="POST" action="<%=urlFor(AdminAction.class)%>">
<table><%

if (ss.isSearchIconVisible())
{
%><tr><td>The search icon is shown in the page header.</td></tr><%

if (hasAdminOpsPerms)
{
%>
<tr><td><input type="hidden" name="hideSearchIcon" value="1"></td></tr>
<tr><td><%= button("Hide Search Icon").submit(true) %></td></tr><%
}
}
else
{
%><tr><td>The search icon is hidden in the page header.</td></tr><%

if (hasAdminOpsPerms)
{
%>
<tr><td><input type="hidden" name="showSearchIcon" value="1"></td></tr>
<tr><td><%= button("Show Search Icon").submit(true) %></td></tr><%
}
}
%>
</table>
</labkey:form></p><%
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.labkey.test.tests.search;

import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.labkey.test.BaseWebDriverTest;
import org.labkey.test.categories.Search;
import org.labkey.test.components.html.SiteNavBar;
import org.labkey.test.util.search.SearchAdminAPIHelper;

import java.util.List;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

@Category({Search.class})
@BaseWebDriverTest.ClassTimeout(minutes = 1)
public class HideSearchIconTest extends BaseWebDriverTest
{
@Override
protected String getProjectName()
{
return null;
}

@Override
public List<String> getAssociatedModules()
{
return List.of("Search");
}

@Test
public void testHideSearchIcon()
{
goToHome();
assertTrue(new SiteNavBar(getDriver()).isSearchIconPresent());

// Hide icon, refresh page, and verify icon is gone
SearchAdminAPIHelper.hideSearchIcon(getDriver());
goToHome();
assertFalse(new SiteNavBar(getDriver()).isSearchIconPresent());

// Show icon, refresh page, and verify icon is back
SearchAdminAPIHelper.showSearchIcon(getDriver());
goToHome();
assertTrue( new SiteNavBar(getDriver()).isSearchIconPresent());
}
}