From 4410101f3fc2eff9538fd53d372ae4025147b9ae Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 12 Feb 2026 09:26:04 -0800 Subject: [PATCH 1/4] Fix wiki delete npe and hide datasource test button (#7401) --- .../src/org/labkey/query/controllers/QueryController.java | 7 ++++--- wiki/src/org/labkey/wiki/WikiController.java | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/query/src/org/labkey/query/controllers/QueryController.java b/query/src/org/labkey/query/controllers/QueryController.java index 35ba9a5d411..0ed4aa66be9 100644 --- a/query/src/org/labkey/query/controllers/QueryController.java +++ b/query/src/org/labkey/query/controllers/QueryController.java @@ -714,7 +714,8 @@ public DataSourceAdminAction(ViewContext viewContext) public ModelAndView getView(Object o, BindException errors) { // Site Admin or Troubleshooter? Troubleshooters can see all the information but can't test data sources. - boolean hasAdminOpsPerms = getContainer().hasPermission(getUser(), AdminOperationsPermission.class); + // Dev mode only, since "Test" is meant for LabKey's own development and testing purposes. + boolean showTestButton = getContainer().hasPermission(getUser(), AdminOperationsPermission.class) && AppProps.getInstance().isDevMode(); List allDefs = QueryManager.get().getExternalSchemaDefs(null); MultiValuedMap byDataSourceName = new ArrayListValuedHashMap<>(); @@ -729,7 +730,7 @@ public ModelAndView getView(Object o, BindException errors) BR(), TABLE(cl("labkey-data-region"), TR(cl("labkey-show-borders"), - hasAdminOpsPerms ? TD(cl("labkey-column-header"), "Test") : null, + showTestButton ? TD(cl("labkey-column-header"), "Test") : null, TD(cl("labkey-column-header"), "Data Source"), TD(cl("labkey-column-header"), "Current Status"), TD(cl("labkey-column-header"), "URL"), @@ -759,7 +760,7 @@ public ModelAndView getView(Object o, BindException errors) return Stream.of( TR( cl(rowStyle), - hasAdminOpsPerms ? TD(connected ? new ButtonBuilder("Test").href(new ActionURL(TestDataSourceConfirmAction.class, getContainer()).addParameter("dataSource", scope.getDataSourceName())) : "") : null, + showTestButton ? TD(connected ? new ButtonBuilder("Test").href(new ActionURL(TestDataSourceConfirmAction.class, getContainer()).addParameter("dataSource", scope.getDataSourceName())) : "") : null, TD(HtmlString.NBSP, scope.getDisplayName()), TD(status), TD(scope.getDatabaseUrl()), diff --git a/wiki/src/org/labkey/wiki/WikiController.java b/wiki/src/org/labkey/wiki/WikiController.java index a26266905d8..a9c9c35cc7a 100644 --- a/wiki/src/org/labkey/wiki/WikiController.java +++ b/wiki/src/org/labkey/wiki/WikiController.java @@ -427,7 +427,7 @@ public ActionURL getCancelUrl() @Override public ActionURL getFailURL(WikiNameForm wikiNameForm, BindException errors) { - return new ManageAction(getViewContext(), _wiki).getUrl(); + return _wiki != null ? new ManageAction(getViewContext(), _wiki).getUrl() : null; } } From a7a48e2657af31985e1aa91eb3b89e2a71162377 Mon Sep 17 00:00:00 2001 From: Susan Hert Date: Mon, 16 Feb 2026 08:03:06 -0800 Subject: [PATCH 2/4] Better handling for an empty UnreferencedSampleFiles table and make test reset flags (#7414) --- .../ExpUnreferencedSampleFilesTableImpl.java | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java b/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java index fb4cbe5ab2f..cdb35f20821 100644 --- a/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java @@ -48,38 +48,42 @@ public FileUnionTable(@NotNull ExpSchema schema) FileContentService svc = FileContentService.get(); _query = new SQLFragment(); - if (svc == null) - return; - - SQLFragment listQuery = svc.listSampleFilesQuery(schema.getUser()); - if (StringUtils.isEmpty(listQuery)) - return; - - TableInfo expDataTable = ExperimentService.get().getTinfoData(); - TableInfo materialTable = ExperimentService.get().getTinfoMaterial(); + SQLFragment listQuery = new SQLFragment(); + if (svc != null) + listQuery = svc.listSampleFilesQuery(schema.getUser()); _query.appendComment("", getSchema().getSqlDialect()); - SQLFragment sampleFileSql = new SQLFragment("SELECT m.Container, if.FilePathShort \n") - .append("FROM (") - .append(svc.listSampleFilesQuery(schema.getUser())) - .append(") AS if \n") - .append("JOIN ") - .append(materialTable, "m") - .append(" ON if.SourceKey = m.RowId"); - - SQLFragment unreferencedFileSql = new SQLFragment("SELECT ed.rowId, ed.name as filename, ed.container, ed.created, ed.createdBy, ed.DataFileUrl FROM ") - .append(expDataTable, "ed") - .append(" LEFT JOIN (") - .append(sampleFileSql) - .append(" ) sf\n") - .append(" ON ed.name = sf.FilePathShort AND ed.container = sf.container\n") - .append(" WHERE ed.datafileurl LIKE ") - .appendValue("%@files/sampletype/%") - .append(" AND sf.FilePathShort IS NULL"); - - _query.append(unreferencedFileSql); + TableInfo expDataTable = ExperimentService.get().getTinfoData(); + if (!StringUtils.isEmpty(listQuery)) + { + TableInfo materialTable = ExperimentService.get().getTinfoMaterial(); + + SQLFragment sampleFileSql = new SQLFragment("SELECT m.Container, if.FilePathShort \n") + .append("FROM (") + .append(listQuery) + .append(") AS if \n") + .append("JOIN ") + .append(materialTable, "m") + .append(" ON if.SourceKey = m.RowId"); + + SQLFragment unreferencedFileSql = new SQLFragment("SELECT ed.rowId, ed.name as filename, ed.container, ed.created, ed.createdBy, ed.DataFileUrl FROM ") + .append(expDataTable, "ed") + .append(" LEFT JOIN (") + .append(sampleFileSql) + .append(" ) sf\n") + .append(" ON ed.name = sf.FilePathShort AND ed.container = sf.container\n") + .append(" WHERE ed.datafileurl LIKE ") + .appendValue("%@files/sampletype/%") + .append(" AND sf.FilePathShort IS NULL"); + + _query.append(unreferencedFileSql); + } + else + { + _query.append("SELECT RowId, FileName, Container, Created, CreatedBy, DataFileUrl FROM ").append(expDataTable).append(" WHERE (1=0)"); + } _query.appendComment("", getSchema().getSqlDialect()); var rowIdCol = new BaseColumnInfo("RowId", this, JdbcType.INTEGER); From df97b93e5b318fad421350c95c358f323632f869 Mon Sep 17 00:00:00 2001 From: Cory Nathe Date: Mon, 16 Feb 2026 10:43:14 -0600 Subject: [PATCH 3/4] ExpUnreferencedSampleFilesTableImpl.FileUnionTable fix for FileContentService NULL case select statement (#7420) - select Name column and alias it as FileName --- .../experiment/api/ExpUnreferencedSampleFilesTableImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java b/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java index cdb35f20821..ffd0e429609 100644 --- a/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpUnreferencedSampleFilesTableImpl.java @@ -82,7 +82,7 @@ public FileUnionTable(@NotNull ExpSchema schema) } else { - _query.append("SELECT RowId, FileName, Container, Created, CreatedBy, DataFileUrl FROM ").append(expDataTable).append(" WHERE (1=0)"); + _query.append("SELECT RowId, Name AS FileName, Container, Created, CreatedBy, DataFileUrl FROM ").append(expDataTable).append(" WHERE (1=0)"); } _query.appendComment("", getSchema().getSqlDialect()); From 8d961f012d5ecc241ccf93e4390d26d1a9284b83 Mon Sep 17 00:00:00 2001 From: Josh Eckels Date: Mon, 16 Feb 2026 15:36:39 -0800 Subject: [PATCH 4/4] Add missing text descriptions for UI elements (#7417) --- api/src/org/labkey/api/view/menu/NavTreeMenu.java | 3 ++- .../core/view/template/bootstrap/ViewServiceImpl.java | 6 ++++-- core/src/org/labkey/core/view/template/bootstrap/header.jsp | 2 +- search/src/org/labkey/search/view/search.jsp | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/api/src/org/labkey/api/view/menu/NavTreeMenu.java b/api/src/org/labkey/api/view/menu/NavTreeMenu.java index a5e57e8a607..7345d4092a8 100644 --- a/api/src/org/labkey/api/view/menu/NavTreeMenu.java +++ b/api/src/org/labkey/api/view/menu/NavTreeMenu.java @@ -201,10 +201,11 @@ private void renderLinks(NavTree nav, int level, String pathToHere, String rootI ActionURL expandCollapseUrl = Objects.requireNonNull(PageFlowUtil.urlProvider(ProjectUrls.class)).getExpandCollapseURL(getViewContext().getContainer(), pathToHere, rootId); String image = collapsed ? "plus.gif" : "minus.gif"; + String altPrefix = collapsed ? "Expand" : "Collapse"; id = config.makeId("navtree"); oldWriter.printf("", id, filter(expandCollapseUrl)); config.addHandler(id, "click", "return LABKEY.Utils.toggleLink(this,true);"); - oldWriter.printf("", context.getContextPath(), image); + oldWriter.printf("\"%s", filter(context.getContextPath()), filter(image), filter(altPrefix), filter(nav.getText())); } else if (indentForExpansionGifs) oldWriter.printf("
"); diff --git a/core/src/org/labkey/core/view/template/bootstrap/ViewServiceImpl.java b/core/src/org/labkey/core/view/template/bootstrap/ViewServiceImpl.java index 08c7d618fe2..23885cce85e 100644 --- a/core/src/org/labkey/core/view/template/bootstrap/ViewServiceImpl.java +++ b/core/src/org/labkey/core/view/template/bootstrap/ViewServiceImpl.java @@ -666,7 +666,7 @@ public void renderCollapsiblePortalTitle(PrintWriter out) public void renderCustomDropDown(String title, NavTree current, PrintWriter out) { - renderMenuWithFontImage(null, current, out, null, false); + renderMenuWithFontImage(title, current, out, null, false); } } @@ -750,7 +750,9 @@ private void renderMenuWithFontImage(String title, NavTree menu, PrintWriter out if (rightAlign) out.print(" pull-right"); out.print("\">"); - out.print(""); out.print(""); 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 e147df531db..a5d95b301f5 100644 --- a/core/src/org/labkey/core/view/template/bootstrap/header.jsp +++ b/core/src/org/labkey/core/view/template/bootstrap/header.jsp @@ -143,7 +143,7 @@ { %>