From cd7df6b469518f88071e89894f3e90715fb7bb73 Mon Sep 17 00:00:00 2001 From: XingY Date: Fri, 22 May 2026 09:54:20 -0700 Subject: [PATCH 1/2] GitHub Issue 1100 & 1021 --- api/src/org/labkey/api/reports/Report.java | 456 +++++++++--------- .../query/reports/view/ReportsWebPart.java | 280 +++++------ .../reports/view/reportsWebPartConfig.jsp | 404 ++++++++-------- 3 files changed, 574 insertions(+), 566 deletions(-) diff --git a/api/src/org/labkey/api/reports/Report.java b/api/src/org/labkey/api/reports/Report.java index 731a651d601..a2886168138 100644 --- a/api/src/org/labkey/api/reports/Report.java +++ b/api/src/org/labkey/api/reports/Report.java @@ -1,224 +1,232 @@ -/* - * Copyright (c) 2008-2019 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.api.reports; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.labkey.api.admin.FolderExportContext; -import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.data.Container; -import org.labkey.api.data.Results; -import org.labkey.api.query.ValidationError; -import org.labkey.api.reports.report.ReportDescriptor; -import org.labkey.api.reports.report.ScriptOutput; -import org.labkey.api.security.User; -import org.labkey.api.security.UserPrincipal; -import org.labkey.api.security.permissions.Permission; -import org.labkey.api.thumbnail.ThumbnailProvider; -import org.labkey.api.util.Pair; -import org.labkey.api.util.SafeToRenderEnum; -import org.labkey.api.view.ActionURL; -import org.labkey.api.view.HttpView; -import org.labkey.api.view.ViewContext; -import org.labkey.api.writer.ContainerUser; -import org.labkey.api.writer.VirtualFile; -import org.springframework.validation.BindException; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -public interface Report extends AttachmentParent, ThumbnailProvider -{ - String SHARE_REPORT_TYPE = "Report.ShareReport"; - - Report clone(); - String getType(); - String getTypeDescription(); - String getDescriptorType(); - - /** - * Render this report in the specified context - */ - HttpView renderReport(ViewContext context) throws Exception; - - /** - * Return the data view (if any) for this report. Many reports are created from a source - * data grid (or query view), this view can be displayed on another tab with the rendered results. - */ - HttpView renderDataView(ViewContext context) throws Exception; - - /** - * Returns a view appropriate for displaying report results, may be a simple view, or - * it may aggregate more than one of the rendered views a report can display. - */ - HttpView getRunReportView(ViewContext context) throws Exception; - - ReportDescriptor getDescriptor(); - void setDescriptor(ReportDescriptor descriptor); - - /** - * Determines whether the user can edit this report - */ - boolean canEdit(User user, Container container); - boolean canEdit(User user, Container container, List errors); - - /** - * Determines whether the user can modify the shared state of a report - */ - boolean canShare(User user, Container container); - boolean canShare(User user, Container container, List errors); - - /** - * Determine if this report type allows sharing via the shareReport action. - */ - boolean allowShareButton(User user, Container container); - - /** - * Determines whether the user can delete this report - */ - boolean canDelete(User user, Container container); - boolean canDelete(User user, Container container, List errors); - - boolean hasPermission(@NotNull UserPrincipal user, @NotNull Container container, @NotNull Class perm); - - /** - * Called before the report is saved to allow any additional save tasks by - * individual reports. - */ - void beforeSave(ContainerUser context); - - /** - * Determine if the report has a modification to its content, in which case we will update the "ContentModified" field - */ - boolean hasContentModified(ContainerUser context); - - /** - * Called before the report is deleted to allow any additional cleanup by - * individual reports. - */ - void beforeDelete(ContainerUser context); - - // TODO: This should take Container, @Nullable ActionURL instead of a full ViewContext to behave for background threads - ActionURL getRunReportURL(ViewContext context); - - /** - * Anchor target (e.g., "_blank") use when rendering run report href. - */ - String getRunReportTarget(); - - @Nullable ActionURL getEditReportURL(ViewContext context); - @Nullable ActionURL getEditReportURL(ViewContext context, ActionURL returnUrl); - - /** - * Allows source grid data to be downloaded for query based reports. This would be most - * commonly used in R reports. - */ - ActionURL getDownloadDataURL(ViewContext context); - - /** - * Optional support for server side report caching - */ - void clearCache(); - - /** - * Generic method to allow serialization of a report. - */ - void serialize(FolderExportContext context, VirtualFile dir, String filename) throws IOException; - - /** - * Serializes a report to a file(s) in the specified directory. Reports will auto-generate - * the eventual file name, reports may generate more than one file. - * - * @param directory - the folder to serialize the report to - */ - void serializeToFolder(FolderExportContext context, VirtualFile directory) throws IOException; - - /** - * Called after import to perform report-specific processing after deserialization from a virtual file. - */ - void afterImport(Container container, User user); - - /** - * Called after save to perform report-specific processing after deserialization from a virtual file - */ - void afterSave(Container container, User user, VirtualFile root); - - /** - * Optional method to perform report-specific processing after file based deserialization - * @param reportMetaFile - the original file containing the report meta-data - */ - void afterDeserializeFromFile(File reportMetaFile) throws IOException; - - /** - * Reports provide a map of key/value properties which represent the report state, this state can be then - * serialized to the database, json, xml etc. - */ - Map serialize(Container container, User user); - - default Map getExternalEditorConfig(ViewContext viewContext) - { - return null; - } - - default Pair startExternalEditor(ViewContext context, String script, BindException errors) - { - return null; - } - - default void saveFromExternalEditor(ContainerUser context, String script) - { - throw new UnsupportedOperationException("No external editor defined for report class " + this.getClass().getSimpleName()); - } - - /** - * Reports which are query or result set oriented, can implement this interface to - * generate the result set from which results are rendered. - */ - - interface ResultSetGenerator - { - // public ResultSet generateResultSet(ViewContext context) throws Exception; - Results generateResults(ViewContext context, boolean allowAsyncQuery) throws Exception; - } - - /** - * Script based reports can execute and return a list of object objects instead - * of rendering into html. The list of script outputs may include errors, console output - * or output parameters. - */ - interface ScriptExecutor - { - List executeScript(ViewContext context, Map inputParameters) throws Exception; - } - - enum renderParam implements SafeToRenderEnum - { - reportWebPart, - reportId, - reportSessionId, - showTabs, - showSection, - reportName, - } - - /* For reports that contain user written code, this indicates whether the runtime environment is sandboxed - * e.g. This report can run code that runs outside labkey's security context - */ - boolean isSandboxed(); -} +/* + * Copyright (c) 2008-2019 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.api.reports; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.labkey.api.admin.FolderExportContext; +import org.labkey.api.attachments.AttachmentParent; +import org.labkey.api.data.Container; +import org.labkey.api.data.Results; +import org.labkey.api.query.ValidationError; +import org.labkey.api.reports.report.ReportDescriptor; +import org.labkey.api.reports.report.ScriptOutput; +import org.labkey.api.security.User; +import org.labkey.api.security.UserPrincipal; +import org.labkey.api.security.permissions.Permission; +import org.labkey.api.thumbnail.ThumbnailProvider; +import org.labkey.api.util.Pair; +import org.labkey.api.util.SafeToRenderEnum; +import org.labkey.api.view.ActionURL; +import org.labkey.api.view.HttpView; +import org.labkey.api.view.ViewContext; +import org.labkey.api.writer.ContainerUser; +import org.labkey.api.writer.VirtualFile; +import org.springframework.validation.BindException; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public interface Report extends AttachmentParent, ThumbnailProvider +{ + String SHARE_REPORT_TYPE = "Report.ShareReport"; + + Report clone(); + String getType(); + String getTypeDescription(); + String getDescriptorType(); + + /** + * Render this report in the specified context + */ + HttpView renderReport(ViewContext context) throws Exception; + + /** + * Return the data view (if any) for this report. Many reports are created from a source + * data grid (or query view), this view can be displayed on another tab with the rendered results. + */ + HttpView renderDataView(ViewContext context) throws Exception; + + /** + * Returns a view appropriate for displaying report results, may be a simple view, or + * it may aggregate more than one of the rendered views a report can display. + */ + HttpView getRunReportView(ViewContext context) throws Exception; + + ReportDescriptor getDescriptor(); + void setDescriptor(ReportDescriptor descriptor); + + /** + * Determines whether the user can edit this report + */ + boolean canEdit(User user, Container container); + boolean canEdit(User user, Container container, List errors); + + /** + * Determines whether the user can modify the shared state of a report + */ + boolean canShare(User user, Container container); + boolean canShare(User user, Container container, List errors); + + /** + * Determine if this report type allows sharing via the shareReport action. + */ + boolean allowShareButton(User user, Container container); + + /** + * Determines whether the user can delete this report + */ + boolean canDelete(User user, Container container); + boolean canDelete(User user, Container container, List errors); + + boolean hasPermission(@NotNull UserPrincipal user, @NotNull Container container, @NotNull Class perm); + + /** + * Called before the report is saved to allow any additional save tasks by + * individual reports. + */ + void beforeSave(ContainerUser context); + + /** + * Determine if the report has a modification to its content, in which case we will update the "ContentModified" field + */ + boolean hasContentModified(ContainerUser context); + + /** + * Called before the report is deleted to allow any additional cleanup by + * individual reports. + */ + void beforeDelete(ContainerUser context); + + // TODO: This should take Container, @Nullable ActionURL instead of a full ViewContext to behave for background threads + ActionURL getRunReportURL(ViewContext context); + + /** + * Anchor target (e.g., "_blank") use when rendering run report href. + */ + String getRunReportTarget(); + + @Nullable ActionURL getEditReportURL(ViewContext context); + @Nullable ActionURL getEditReportURL(ViewContext context, ActionURL returnUrl); + + /** + * Allows source grid data to be downloaded for query based reports. This would be most + * commonly used in R reports. + */ + ActionURL getDownloadDataURL(ViewContext context); + + /** + * Optional support for server side report caching + */ + void clearCache(); + + /** + * Generic method to allow serialization of a report. + */ + void serialize(FolderExportContext context, VirtualFile dir, String filename) throws IOException; + + /** + * Serializes a report to a file(s) in the specified directory. Reports will auto-generate + * the eventual file name, reports may generate more than one file. + * + * @param directory - the folder to serialize the report to + */ + void serializeToFolder(FolderExportContext context, VirtualFile directory) throws IOException; + + /** + * Called after import to perform report-specific processing after deserialization from a virtual file. + */ + void afterImport(Container container, User user); + + /** + * Called after save to perform report-specific processing after deserialization from a virtual file + */ + void afterSave(Container container, User user, VirtualFile root); + + /** + * Optional method to perform report-specific processing after file based deserialization + * @param reportMetaFile - the original file containing the report meta-data + */ + void afterDeserializeFromFile(File reportMetaFile) throws IOException; + + /** + * Reports provide a map of key/value properties which represent the report state, this state can be then + * serialized to the database, json, xml etc. + */ + Map serialize(Container container, User user); + + default Map getExternalEditorConfig(ViewContext viewContext) + { + return null; + } + + default Pair startExternalEditor(ViewContext context, String script, BindException errors) + { + return null; + } + + default void saveFromExternalEditor(ContainerUser context, String script) + { + throw new UnsupportedOperationException("No external editor defined for report class " + this.getClass().getSimpleName()); + } + + /** + * Reports which are query or result set oriented, can implement this interface to + * generate the result set from which results are rendered. + */ + + interface ResultSetGenerator + { + // public ResultSet generateResultSet(ViewContext context) throws Exception; + Results generateResults(ViewContext context, boolean allowAsyncQuery) throws Exception; + } + + /** + * Script based reports can execute and return a list of object objects instead + * of rendering into html. The list of script outputs may include errors, console output + * or output parameters. + */ + interface ScriptExecutor + { + List executeScript(ViewContext context, Map inputParameters) throws Exception; + } + + enum renderParam implements SafeToRenderEnum + { + reportWebPart, + reportId, + reportSessionId, + showTabs, + showSection, + reportName, + } + + /* For reports that contain user written code, this indicates whether the runtime environment is sandboxed + * e.g. This report can run code that runs outside labkey's security context + */ + boolean isSandboxed(); + + /* Reports that require a redirect (e.g., Sample Finder saved searches) should return false + * to prevent them from causing invalid redirects during web part rendering. + */ + default boolean isShowInReportsWebPart() + { + return true; + } +} diff --git a/query/src/org/labkey/query/reports/view/ReportsWebPart.java b/query/src/org/labkey/query/reports/view/ReportsWebPart.java index 8f3079f985f..87d8708a25d 100644 --- a/query/src/org/labkey/query/reports/view/ReportsWebPart.java +++ b/query/src/org/labkey/query/reports/view/ReportsWebPart.java @@ -1,140 +1,140 @@ -/* - * Copyright (c) 2008-2019 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.query.reports.view; - -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; -import org.labkey.api.premium.PremiumService; -import org.labkey.api.query.QueryParam; -import org.labkey.api.reports.Report; -import org.labkey.api.reports.report.r.RReport; -import org.labkey.api.reports.report.ReportDescriptor; -import org.labkey.api.reports.report.ScriptReportDescriptor; -import org.labkey.api.reports.report.view.RenderBackgroundRReportView; -import org.labkey.api.reports.report.view.ReportUtil; -import org.labkey.api.view.HtmlView; -import org.labkey.api.view.HttpView; -import org.labkey.api.view.Portal; -import org.labkey.api.view.ViewContext; -import org.labkey.api.view.WebPartView; -import org.labkey.api.writer.HtmlWriter; - -import java.util.Map; -import java.util.Objects; - -public class ReportsWebPart extends WebPartView -{ - Portal.WebPart _webPart; - Report _report; - - public ReportsWebPart(ViewContext context, Portal.WebPart part) - { - super(FrameType.PORTAL); - - _webPart = part; - Map properties = part.getPropertyMap(); - - String title = Objects.toString(properties.get("title"), "Reports"); - setTitle(title); - - try - { - _report = getReport(properties); - if (null != _report) - { - setTitleHref(_report.getRunReportURL(context)); - addClientDependencies(_report.getDescriptor().getClientDependencies()); - } - } - catch (Exception x) - { - } - } - - - @Override - protected void renderView(Object model, HtmlWriter out) throws Exception - { - Map properties = _webPart.getPropertyMap(); - - if (null == _report) - _report = getReport(properties); - - boolean showTabs = BooleanUtils.toBoolean(properties.get(Report.renderParam.showTabs.name())); - getViewContext().put(Report.renderParam.reportWebPart.name(), "true"); - - if (properties.containsKey(Report.renderParam.showSection.name())) - getViewContext().put(Report.renderParam.showSection.name(), properties.get(Report.renderParam.showSection.name())); - - if (PremiumService.get().isRemoteREnabled()) - { - if (properties.containsKey(Report.renderParam.reportSessionId.name())) - getViewContext().put(Report.renderParam.reportSessionId.name(), properties.get(Report.renderParam.reportSessionId.name())); - } - - if (_report != null) - { - HttpView view; - - if (showTabs) - { - view = _report.getRunReportView(getViewContext()); - } - else - { - ReportDescriptor descriptor = _report.getDescriptor(); - boolean runInBackground = BooleanUtils.toBoolean(descriptor.getProperty(ScriptReportDescriptor.Prop.runInBackground)); - - // for now, limit pipeline view to saved R reports - if (runInBackground && _report instanceof RReport) - view = new RenderBackgroundRReportView((RReport)_report); - else - view = _report.renderReport(getViewContext()); - } - - if (view != null) - { - include(view); - return; - } - } - include(HtmlView.of("Unable to display the specified report.")); - } - - - private Report getReport(Map props) - { - Report report = null; - - String reportIdString = props.get(Report.renderParam.reportId.name()); - if (reportIdString != null) - { - report = ReportUtil.getReportById(getViewContext(), reportIdString); - } - else - { - // try schema/query/reportName combo - String reportName = props.get(Report.renderParam.reportName.name()); - if (!StringUtils.isEmpty(reportName)) - { - String key = StringUtils.trimToNull(ReportUtil.getReportKey(props.get(QueryParam.schemaName.name()), props.get(QueryParam.queryName.name()))); - report = ReportUtil.getReportByName(getViewContext(), reportName, key); - } - } - return report; - } -} +/* + * Copyright (c) 2008-2019 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.query.reports.view; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.labkey.api.premium.PremiumService; +import org.labkey.api.query.QueryParam; +import org.labkey.api.reports.Report; +import org.labkey.api.reports.report.r.RReport; +import org.labkey.api.reports.report.ReportDescriptor; +import org.labkey.api.reports.report.ScriptReportDescriptor; +import org.labkey.api.reports.report.view.RenderBackgroundRReportView; +import org.labkey.api.reports.report.view.ReportUtil; +import org.labkey.api.view.HtmlView; +import org.labkey.api.view.HttpView; +import org.labkey.api.view.Portal; +import org.labkey.api.view.ViewContext; +import org.labkey.api.view.WebPartView; +import org.labkey.api.writer.HtmlWriter; + +import java.util.Map; +import java.util.Objects; + +public class ReportsWebPart extends WebPartView +{ + Portal.WebPart _webPart; + Report _report; + + public ReportsWebPart(ViewContext context, Portal.WebPart part) + { + super(FrameType.PORTAL); + + _webPart = part; + Map properties = part.getPropertyMap(); + + String title = Objects.toString(properties.get("title"), "Reports"); + setTitle(title); + + try + { + _report = getReport(properties); + if (null != _report) + { + setTitleHref(_report.getRunReportURL(context)); + addClientDependencies(_report.getDescriptor().getClientDependencies()); + } + } + catch (Exception x) + { + } + } + + + @Override + protected void renderView(Object model, HtmlWriter out) throws Exception + { + Map properties = _webPart.getPropertyMap(); + + if (null == _report) + _report = getReport(properties); + + boolean showTabs = BooleanUtils.toBoolean(properties.get(Report.renderParam.showTabs.name())); + getViewContext().put(Report.renderParam.reportWebPart.name(), "true"); + + if (properties.containsKey(Report.renderParam.showSection.name())) + getViewContext().put(Report.renderParam.showSection.name(), properties.get(Report.renderParam.showSection.name())); + + if (PremiumService.get().isRemoteREnabled()) + { + if (properties.containsKey(Report.renderParam.reportSessionId.name())) + getViewContext().put(Report.renderParam.reportSessionId.name(), properties.get(Report.renderParam.reportSessionId.name())); + } + + if (_report != null && _report.isShowInReportsWebPart()) + { + HttpView view; + + if (showTabs) + { + view = _report.getRunReportView(getViewContext()); + } + else + { + ReportDescriptor descriptor = _report.getDescriptor(); + boolean runInBackground = BooleanUtils.toBoolean(descriptor.getProperty(ScriptReportDescriptor.Prop.runInBackground)); + + // for now, limit pipeline view to saved R reports + if (runInBackground && _report instanceof RReport) + view = new RenderBackgroundRReportView((RReport)_report); + else + view = _report.renderReport(getViewContext()); + } + + if (view != null) + { + include(view); + return; + } + } + include(HtmlView.of("Unable to display the specified report.")); + } + + + private Report getReport(Map props) + { + Report report = null; + + String reportIdString = props.get(Report.renderParam.reportId.name()); + if (reportIdString != null) + { + report = ReportUtil.getReportById(getViewContext(), reportIdString); + } + else + { + // try schema/query/reportName combo + String reportName = props.get(Report.renderParam.reportName.name()); + if (!StringUtils.isEmpty(reportName)) + { + String key = StringUtils.trimToNull(ReportUtil.getReportKey(props.get(QueryParam.schemaName.name()), props.get(QueryParam.queryName.name()))); + report = ReportUtil.getReportByName(getViewContext(), reportName, key); + } + } + return report; + } +} diff --git a/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp b/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp index 5e46ee09588..32dffb4c1c9 100644 --- a/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp +++ b/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp @@ -1,202 +1,202 @@ -<% -/* - * Copyright (c) 2008-2019 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. - */ -%> -<%@ page import="org.apache.commons.lang3.BooleanUtils" %> -<%@ page import="org.apache.commons.lang3.StringUtils" %> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.reports.Report" %> -<%@ page import="org.labkey.api.reports.report.ReportDescriptor" %> -<%@ page import="org.labkey.api.reports.report.ReportUrls" %> -<%@ page import="org.labkey.api.reports.report.view.ReportUtil" %> -<%@ page import="org.labkey.api.security.User" %> -<%@ page import="org.labkey.api.security.permissions.AdminPermission" %> -<%@ page import="org.labkey.api.util.PageFlowUtil" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.api.view.Portal" %> -<%@ page import="org.labkey.api.view.ViewContext" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.LinkedHashMap" %> -<%@ page import="java.util.Map" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> - -<% - JspView me = HttpView.currentView(); - Portal.WebPart webPart = me.getModelBean(); - ViewContext context = getViewContext(); - - Map pm = webPart.getPropertyMap(); - - Map reportMap = new LinkedHashMap<>(); - ArrayList reportNames = new ArrayList<>(); - - ReportUtil.ReportFilter filter = new ReportUtil.DefaultReportFilter(); - Container c = getContainer(); - User u = getUser(); - boolean showHidden = c.hasPermission(u, AdminPermission.class); - - for (Report report : ReportUtil.getReportsIncludingInherited(c, u, null)) - { - if (!filter.accept(report, c, u) || (report.getDescriptor().isHidden() && !showHidden)) - continue; - - String reportName = report.getDescriptor().getReportName(); - if (!StringUtils.isEmpty(reportName)) - { - if (report.getDescriptor().isHidden()) - reportName = reportName + " (hidden)"; - reportMap.put(reportName, report.getDescriptor().getReportId().toString()); - reportNames.add(reportName); - } - } - reportNames.sort(String.CASE_INSENSITIVE_ORDER); - - String sectionName = Report.renderParam.showSection.name(); - String showTabs = Report.renderParam.showTabs.name(); -%> - - - - - - - - - - - - - - <% addHandler("showTabs", "click", "return onShowTabs(this.checked);"); %> - - - - - <% addHandler("showSection", "change", "return selectSection();"); %> - - - - - -
Web Part Title:">
Report or Chart: - <% addHandler("reportId", "change", "getSectionNames(this);"); %> - -
Show Tabs:<%=helpPopup("Show tabs", - "Some reports/charts may be rendered with multiple tabs showing. Select this option to only show the primary one.")%>>
Visible Report Sections:<%=helpPopup("Show Report sections", - "Some reports/charts contain multiple sections such as: images, text, console output. For these types of report, you can select which section(s) to " + - "display by selecting them from the list.")%>
-
- -
- - +<% +/* + * Copyright (c) 2008-2019 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. + */ +%> +<%@ page import="org.apache.commons.lang3.BooleanUtils" %> +<%@ page import="org.apache.commons.lang3.StringUtils" %> +<%@ page import="org.labkey.api.data.Container" %> +<%@ page import="org.labkey.api.reports.Report" %> +<%@ page import="org.labkey.api.reports.report.ReportDescriptor" %> +<%@ page import="org.labkey.api.reports.report.ReportUrls" %> +<%@ page import="org.labkey.api.reports.report.view.ReportUtil" %> +<%@ page import="org.labkey.api.security.User" %> +<%@ page import="org.labkey.api.security.permissions.AdminPermission" %> +<%@ page import="org.labkey.api.util.PageFlowUtil" %> +<%@ page import="org.labkey.api.view.HttpView" %> +<%@ page import="org.labkey.api.view.JspView" %> +<%@ page import="org.labkey.api.view.Portal" %> +<%@ page import="org.labkey.api.view.ViewContext" %> +<%@ page import="java.util.ArrayList" %> +<%@ page import="java.util.LinkedHashMap" %> +<%@ page import="java.util.Map" %> +<%@ page extends="org.labkey.api.jsp.JspBase" %> +<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> + +<% + JspView me = HttpView.currentView(); + Portal.WebPart webPart = me.getModelBean(); + ViewContext context = getViewContext(); + + Map pm = webPart.getPropertyMap(); + + Map reportMap = new LinkedHashMap<>(); + ArrayList reportNames = new ArrayList<>(); + + ReportUtil.ReportFilter filter = new ReportUtil.DefaultReportFilter(); + Container c = getContainer(); + User u = getUser(); + boolean showHidden = c.hasPermission(u, AdminPermission.class); + + for (Report report : ReportUtil.getReportsIncludingInherited(c, u, null)) + { + if (!filter.accept(report, c, u) || (report.getDescriptor().isHidden() && !showHidden) || !report.isShowInReportsWebPart()) + continue; + + String reportName = report.getDescriptor().getReportName(); + if (!StringUtils.isEmpty(reportName)) + { + if (report.getDescriptor().isHidden()) + reportName = reportName + " (hidden)"; + reportMap.put(reportName, report.getDescriptor().getReportId().toString()); + reportNames.add(reportName); + } + } + reportNames.sort(String.CASE_INSENSITIVE_ORDER); + + String sectionName = Report.renderParam.showSection.name(); + String showTabs = Report.renderParam.showTabs.name(); +%> + + + + + + + + + + + + + + <% addHandler("showTabs", "click", "return onShowTabs(this.checked);"); %> + + + + + <% addHandler("showSection", "change", "return selectSection();"); %> + + + + + +
Web Part Title:">
Report or Chart: + <% addHandler("reportId", "change", "getSectionNames(this);"); %> + +
Show Tabs:<%=helpPopup("Show tabs", + "Some reports/charts may be rendered with multiple tabs showing. Select this option to only show the primary one.")%>>
Visible Report Sections:<%=helpPopup("Show Report sections", + "Some reports/charts contain multiple sections such as: images, text, console output. For these types of report, you can select which section(s) to " + + "display by selecting them from the list.")%>
+
+ +
+ + From ab16a7085334db471158c8a0faf57cdef62b4998 Mon Sep 17 00:00:00 2001 From: XingY Date: Fri, 22 May 2026 09:57:45 -0700 Subject: [PATCH 2/2] crlf --- api/src/org/labkey/api/reports/Report.java | 464 +++++++++--------- .../query/reports/view/ReportsWebPart.java | 280 +++++------ .../reports/view/reportsWebPartConfig.jsp | 404 +++++++-------- 3 files changed, 574 insertions(+), 574 deletions(-) diff --git a/api/src/org/labkey/api/reports/Report.java b/api/src/org/labkey/api/reports/Report.java index a2886168138..94d70d752b0 100644 --- a/api/src/org/labkey/api/reports/Report.java +++ b/api/src/org/labkey/api/reports/Report.java @@ -1,232 +1,232 @@ -/* - * Copyright (c) 2008-2019 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.api.reports; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.labkey.api.admin.FolderExportContext; -import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.data.Container; -import org.labkey.api.data.Results; -import org.labkey.api.query.ValidationError; -import org.labkey.api.reports.report.ReportDescriptor; -import org.labkey.api.reports.report.ScriptOutput; -import org.labkey.api.security.User; -import org.labkey.api.security.UserPrincipal; -import org.labkey.api.security.permissions.Permission; -import org.labkey.api.thumbnail.ThumbnailProvider; -import org.labkey.api.util.Pair; -import org.labkey.api.util.SafeToRenderEnum; -import org.labkey.api.view.ActionURL; -import org.labkey.api.view.HttpView; -import org.labkey.api.view.ViewContext; -import org.labkey.api.writer.ContainerUser; -import org.labkey.api.writer.VirtualFile; -import org.springframework.validation.BindException; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -public interface Report extends AttachmentParent, ThumbnailProvider -{ - String SHARE_REPORT_TYPE = "Report.ShareReport"; - - Report clone(); - String getType(); - String getTypeDescription(); - String getDescriptorType(); - - /** - * Render this report in the specified context - */ - HttpView renderReport(ViewContext context) throws Exception; - - /** - * Return the data view (if any) for this report. Many reports are created from a source - * data grid (or query view), this view can be displayed on another tab with the rendered results. - */ - HttpView renderDataView(ViewContext context) throws Exception; - - /** - * Returns a view appropriate for displaying report results, may be a simple view, or - * it may aggregate more than one of the rendered views a report can display. - */ - HttpView getRunReportView(ViewContext context) throws Exception; - - ReportDescriptor getDescriptor(); - void setDescriptor(ReportDescriptor descriptor); - - /** - * Determines whether the user can edit this report - */ - boolean canEdit(User user, Container container); - boolean canEdit(User user, Container container, List errors); - - /** - * Determines whether the user can modify the shared state of a report - */ - boolean canShare(User user, Container container); - boolean canShare(User user, Container container, List errors); - - /** - * Determine if this report type allows sharing via the shareReport action. - */ - boolean allowShareButton(User user, Container container); - - /** - * Determines whether the user can delete this report - */ - boolean canDelete(User user, Container container); - boolean canDelete(User user, Container container, List errors); - - boolean hasPermission(@NotNull UserPrincipal user, @NotNull Container container, @NotNull Class perm); - - /** - * Called before the report is saved to allow any additional save tasks by - * individual reports. - */ - void beforeSave(ContainerUser context); - - /** - * Determine if the report has a modification to its content, in which case we will update the "ContentModified" field - */ - boolean hasContentModified(ContainerUser context); - - /** - * Called before the report is deleted to allow any additional cleanup by - * individual reports. - */ - void beforeDelete(ContainerUser context); - - // TODO: This should take Container, @Nullable ActionURL instead of a full ViewContext to behave for background threads - ActionURL getRunReportURL(ViewContext context); - - /** - * Anchor target (e.g., "_blank") use when rendering run report href. - */ - String getRunReportTarget(); - - @Nullable ActionURL getEditReportURL(ViewContext context); - @Nullable ActionURL getEditReportURL(ViewContext context, ActionURL returnUrl); - - /** - * Allows source grid data to be downloaded for query based reports. This would be most - * commonly used in R reports. - */ - ActionURL getDownloadDataURL(ViewContext context); - - /** - * Optional support for server side report caching - */ - void clearCache(); - - /** - * Generic method to allow serialization of a report. - */ - void serialize(FolderExportContext context, VirtualFile dir, String filename) throws IOException; - - /** - * Serializes a report to a file(s) in the specified directory. Reports will auto-generate - * the eventual file name, reports may generate more than one file. - * - * @param directory - the folder to serialize the report to - */ - void serializeToFolder(FolderExportContext context, VirtualFile directory) throws IOException; - - /** - * Called after import to perform report-specific processing after deserialization from a virtual file. - */ - void afterImport(Container container, User user); - - /** - * Called after save to perform report-specific processing after deserialization from a virtual file - */ - void afterSave(Container container, User user, VirtualFile root); - - /** - * Optional method to perform report-specific processing after file based deserialization - * @param reportMetaFile - the original file containing the report meta-data - */ - void afterDeserializeFromFile(File reportMetaFile) throws IOException; - - /** - * Reports provide a map of key/value properties which represent the report state, this state can be then - * serialized to the database, json, xml etc. - */ - Map serialize(Container container, User user); - - default Map getExternalEditorConfig(ViewContext viewContext) - { - return null; - } - - default Pair startExternalEditor(ViewContext context, String script, BindException errors) - { - return null; - } - - default void saveFromExternalEditor(ContainerUser context, String script) - { - throw new UnsupportedOperationException("No external editor defined for report class " + this.getClass().getSimpleName()); - } - - /** - * Reports which are query or result set oriented, can implement this interface to - * generate the result set from which results are rendered. - */ - - interface ResultSetGenerator - { - // public ResultSet generateResultSet(ViewContext context) throws Exception; - Results generateResults(ViewContext context, boolean allowAsyncQuery) throws Exception; - } - - /** - * Script based reports can execute and return a list of object objects instead - * of rendering into html. The list of script outputs may include errors, console output - * or output parameters. - */ - interface ScriptExecutor - { - List executeScript(ViewContext context, Map inputParameters) throws Exception; - } - - enum renderParam implements SafeToRenderEnum - { - reportWebPart, - reportId, - reportSessionId, - showTabs, - showSection, - reportName, - } - - /* For reports that contain user written code, this indicates whether the runtime environment is sandboxed - * e.g. This report can run code that runs outside labkey's security context - */ - boolean isSandboxed(); - - /* Reports that require a redirect (e.g., Sample Finder saved searches) should return false - * to prevent them from causing invalid redirects during web part rendering. - */ - default boolean isShowInReportsWebPart() - { - return true; - } -} +/* + * Copyright (c) 2008-2019 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.api.reports; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.labkey.api.admin.FolderExportContext; +import org.labkey.api.attachments.AttachmentParent; +import org.labkey.api.data.Container; +import org.labkey.api.data.Results; +import org.labkey.api.query.ValidationError; +import org.labkey.api.reports.report.ReportDescriptor; +import org.labkey.api.reports.report.ScriptOutput; +import org.labkey.api.security.User; +import org.labkey.api.security.UserPrincipal; +import org.labkey.api.security.permissions.Permission; +import org.labkey.api.thumbnail.ThumbnailProvider; +import org.labkey.api.util.Pair; +import org.labkey.api.util.SafeToRenderEnum; +import org.labkey.api.view.ActionURL; +import org.labkey.api.view.HttpView; +import org.labkey.api.view.ViewContext; +import org.labkey.api.writer.ContainerUser; +import org.labkey.api.writer.VirtualFile; +import org.springframework.validation.BindException; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public interface Report extends AttachmentParent, ThumbnailProvider +{ + String SHARE_REPORT_TYPE = "Report.ShareReport"; + + Report clone(); + String getType(); + String getTypeDescription(); + String getDescriptorType(); + + /** + * Render this report in the specified context + */ + HttpView renderReport(ViewContext context) throws Exception; + + /** + * Return the data view (if any) for this report. Many reports are created from a source + * data grid (or query view), this view can be displayed on another tab with the rendered results. + */ + HttpView renderDataView(ViewContext context) throws Exception; + + /** + * Returns a view appropriate for displaying report results, may be a simple view, or + * it may aggregate more than one of the rendered views a report can display. + */ + HttpView getRunReportView(ViewContext context) throws Exception; + + ReportDescriptor getDescriptor(); + void setDescriptor(ReportDescriptor descriptor); + + /** + * Determines whether the user can edit this report + */ + boolean canEdit(User user, Container container); + boolean canEdit(User user, Container container, List errors); + + /** + * Determines whether the user can modify the shared state of a report + */ + boolean canShare(User user, Container container); + boolean canShare(User user, Container container, List errors); + + /** + * Determine if this report type allows sharing via the shareReport action. + */ + boolean allowShareButton(User user, Container container); + + /** + * Determines whether the user can delete this report + */ + boolean canDelete(User user, Container container); + boolean canDelete(User user, Container container, List errors); + + boolean hasPermission(@NotNull UserPrincipal user, @NotNull Container container, @NotNull Class perm); + + /** + * Called before the report is saved to allow any additional save tasks by + * individual reports. + */ + void beforeSave(ContainerUser context); + + /** + * Determine if the report has a modification to its content, in which case we will update the "ContentModified" field + */ + boolean hasContentModified(ContainerUser context); + + /** + * Called before the report is deleted to allow any additional cleanup by + * individual reports. + */ + void beforeDelete(ContainerUser context); + + // TODO: This should take Container, @Nullable ActionURL instead of a full ViewContext to behave for background threads + ActionURL getRunReportURL(ViewContext context); + + /** + * Anchor target (e.g., "_blank") use when rendering run report href. + */ + String getRunReportTarget(); + + @Nullable ActionURL getEditReportURL(ViewContext context); + @Nullable ActionURL getEditReportURL(ViewContext context, ActionURL returnUrl); + + /** + * Allows source grid data to be downloaded for query based reports. This would be most + * commonly used in R reports. + */ + ActionURL getDownloadDataURL(ViewContext context); + + /** + * Optional support for server side report caching + */ + void clearCache(); + + /** + * Generic method to allow serialization of a report. + */ + void serialize(FolderExportContext context, VirtualFile dir, String filename) throws IOException; + + /** + * Serializes a report to a file(s) in the specified directory. Reports will auto-generate + * the eventual file name, reports may generate more than one file. + * + * @param directory - the folder to serialize the report to + */ + void serializeToFolder(FolderExportContext context, VirtualFile directory) throws IOException; + + /** + * Called after import to perform report-specific processing after deserialization from a virtual file. + */ + void afterImport(Container container, User user); + + /** + * Called after save to perform report-specific processing after deserialization from a virtual file + */ + void afterSave(Container container, User user, VirtualFile root); + + /** + * Optional method to perform report-specific processing after file based deserialization + * @param reportMetaFile - the original file containing the report meta-data + */ + void afterDeserializeFromFile(File reportMetaFile) throws IOException; + + /** + * Reports provide a map of key/value properties which represent the report state, this state can be then + * serialized to the database, json, xml etc. + */ + Map serialize(Container container, User user); + + default Map getExternalEditorConfig(ViewContext viewContext) + { + return null; + } + + default Pair startExternalEditor(ViewContext context, String script, BindException errors) + { + return null; + } + + default void saveFromExternalEditor(ContainerUser context, String script) + { + throw new UnsupportedOperationException("No external editor defined for report class " + this.getClass().getSimpleName()); + } + + /** + * Reports which are query or result set oriented, can implement this interface to + * generate the result set from which results are rendered. + */ + + interface ResultSetGenerator + { + // public ResultSet generateResultSet(ViewContext context) throws Exception; + Results generateResults(ViewContext context, boolean allowAsyncQuery) throws Exception; + } + + /** + * Script based reports can execute and return a list of object objects instead + * of rendering into html. The list of script outputs may include errors, console output + * or output parameters. + */ + interface ScriptExecutor + { + List executeScript(ViewContext context, Map inputParameters) throws Exception; + } + + enum renderParam implements SafeToRenderEnum + { + reportWebPart, + reportId, + reportSessionId, + showTabs, + showSection, + reportName, + } + + /* For reports that contain user written code, this indicates whether the runtime environment is sandboxed + * e.g. This report can run code that runs outside labkey's security context + */ + boolean isSandboxed(); + + /* Reports that require a redirect (e.g., Sample Finder saved searches) should return false + * to prevent them from causing invalid redirects during web part rendering. + */ + default boolean isShowInReportsWebPart() + { + return true; + } +} diff --git a/query/src/org/labkey/query/reports/view/ReportsWebPart.java b/query/src/org/labkey/query/reports/view/ReportsWebPart.java index 87d8708a25d..1f30990bfaf 100644 --- a/query/src/org/labkey/query/reports/view/ReportsWebPart.java +++ b/query/src/org/labkey/query/reports/view/ReportsWebPart.java @@ -1,140 +1,140 @@ -/* - * Copyright (c) 2008-2019 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.query.reports.view; - -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; -import org.labkey.api.premium.PremiumService; -import org.labkey.api.query.QueryParam; -import org.labkey.api.reports.Report; -import org.labkey.api.reports.report.r.RReport; -import org.labkey.api.reports.report.ReportDescriptor; -import org.labkey.api.reports.report.ScriptReportDescriptor; -import org.labkey.api.reports.report.view.RenderBackgroundRReportView; -import org.labkey.api.reports.report.view.ReportUtil; -import org.labkey.api.view.HtmlView; -import org.labkey.api.view.HttpView; -import org.labkey.api.view.Portal; -import org.labkey.api.view.ViewContext; -import org.labkey.api.view.WebPartView; -import org.labkey.api.writer.HtmlWriter; - -import java.util.Map; -import java.util.Objects; - -public class ReportsWebPart extends WebPartView -{ - Portal.WebPart _webPart; - Report _report; - - public ReportsWebPart(ViewContext context, Portal.WebPart part) - { - super(FrameType.PORTAL); - - _webPart = part; - Map properties = part.getPropertyMap(); - - String title = Objects.toString(properties.get("title"), "Reports"); - setTitle(title); - - try - { - _report = getReport(properties); - if (null != _report) - { - setTitleHref(_report.getRunReportURL(context)); - addClientDependencies(_report.getDescriptor().getClientDependencies()); - } - } - catch (Exception x) - { - } - } - - - @Override - protected void renderView(Object model, HtmlWriter out) throws Exception - { - Map properties = _webPart.getPropertyMap(); - - if (null == _report) - _report = getReport(properties); - - boolean showTabs = BooleanUtils.toBoolean(properties.get(Report.renderParam.showTabs.name())); - getViewContext().put(Report.renderParam.reportWebPart.name(), "true"); - - if (properties.containsKey(Report.renderParam.showSection.name())) - getViewContext().put(Report.renderParam.showSection.name(), properties.get(Report.renderParam.showSection.name())); - - if (PremiumService.get().isRemoteREnabled()) - { - if (properties.containsKey(Report.renderParam.reportSessionId.name())) - getViewContext().put(Report.renderParam.reportSessionId.name(), properties.get(Report.renderParam.reportSessionId.name())); - } - - if (_report != null && _report.isShowInReportsWebPart()) - { - HttpView view; - - if (showTabs) - { - view = _report.getRunReportView(getViewContext()); - } - else - { - ReportDescriptor descriptor = _report.getDescriptor(); - boolean runInBackground = BooleanUtils.toBoolean(descriptor.getProperty(ScriptReportDescriptor.Prop.runInBackground)); - - // for now, limit pipeline view to saved R reports - if (runInBackground && _report instanceof RReport) - view = new RenderBackgroundRReportView((RReport)_report); - else - view = _report.renderReport(getViewContext()); - } - - if (view != null) - { - include(view); - return; - } - } - include(HtmlView.of("Unable to display the specified report.")); - } - - - private Report getReport(Map props) - { - Report report = null; - - String reportIdString = props.get(Report.renderParam.reportId.name()); - if (reportIdString != null) - { - report = ReportUtil.getReportById(getViewContext(), reportIdString); - } - else - { - // try schema/query/reportName combo - String reportName = props.get(Report.renderParam.reportName.name()); - if (!StringUtils.isEmpty(reportName)) - { - String key = StringUtils.trimToNull(ReportUtil.getReportKey(props.get(QueryParam.schemaName.name()), props.get(QueryParam.queryName.name()))); - report = ReportUtil.getReportByName(getViewContext(), reportName, key); - } - } - return report; - } -} +/* + * Copyright (c) 2008-2019 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.query.reports.view; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.labkey.api.premium.PremiumService; +import org.labkey.api.query.QueryParam; +import org.labkey.api.reports.Report; +import org.labkey.api.reports.report.r.RReport; +import org.labkey.api.reports.report.ReportDescriptor; +import org.labkey.api.reports.report.ScriptReportDescriptor; +import org.labkey.api.reports.report.view.RenderBackgroundRReportView; +import org.labkey.api.reports.report.view.ReportUtil; +import org.labkey.api.view.HtmlView; +import org.labkey.api.view.HttpView; +import org.labkey.api.view.Portal; +import org.labkey.api.view.ViewContext; +import org.labkey.api.view.WebPartView; +import org.labkey.api.writer.HtmlWriter; + +import java.util.Map; +import java.util.Objects; + +public class ReportsWebPart extends WebPartView +{ + Portal.WebPart _webPart; + Report _report; + + public ReportsWebPart(ViewContext context, Portal.WebPart part) + { + super(FrameType.PORTAL); + + _webPart = part; + Map properties = part.getPropertyMap(); + + String title = Objects.toString(properties.get("title"), "Reports"); + setTitle(title); + + try + { + _report = getReport(properties); + if (null != _report) + { + setTitleHref(_report.getRunReportURL(context)); + addClientDependencies(_report.getDescriptor().getClientDependencies()); + } + } + catch (Exception x) + { + } + } + + + @Override + protected void renderView(Object model, HtmlWriter out) throws Exception + { + Map properties = _webPart.getPropertyMap(); + + if (null == _report) + _report = getReport(properties); + + boolean showTabs = BooleanUtils.toBoolean(properties.get(Report.renderParam.showTabs.name())); + getViewContext().put(Report.renderParam.reportWebPart.name(), "true"); + + if (properties.containsKey(Report.renderParam.showSection.name())) + getViewContext().put(Report.renderParam.showSection.name(), properties.get(Report.renderParam.showSection.name())); + + if (PremiumService.get().isRemoteREnabled()) + { + if (properties.containsKey(Report.renderParam.reportSessionId.name())) + getViewContext().put(Report.renderParam.reportSessionId.name(), properties.get(Report.renderParam.reportSessionId.name())); + } + + if (_report != null && _report.isShowInReportsWebPart()) + { + HttpView view; + + if (showTabs) + { + view = _report.getRunReportView(getViewContext()); + } + else + { + ReportDescriptor descriptor = _report.getDescriptor(); + boolean runInBackground = BooleanUtils.toBoolean(descriptor.getProperty(ScriptReportDescriptor.Prop.runInBackground)); + + // for now, limit pipeline view to saved R reports + if (runInBackground && _report instanceof RReport) + view = new RenderBackgroundRReportView((RReport)_report); + else + view = _report.renderReport(getViewContext()); + } + + if (view != null) + { + include(view); + return; + } + } + include(HtmlView.of("Unable to display the specified report.")); + } + + + private Report getReport(Map props) + { + Report report = null; + + String reportIdString = props.get(Report.renderParam.reportId.name()); + if (reportIdString != null) + { + report = ReportUtil.getReportById(getViewContext(), reportIdString); + } + else + { + // try schema/query/reportName combo + String reportName = props.get(Report.renderParam.reportName.name()); + if (!StringUtils.isEmpty(reportName)) + { + String key = StringUtils.trimToNull(ReportUtil.getReportKey(props.get(QueryParam.schemaName.name()), props.get(QueryParam.queryName.name()))); + report = ReportUtil.getReportByName(getViewContext(), reportName, key); + } + } + return report; + } +} diff --git a/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp b/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp index 32dffb4c1c9..00e9ddcbe99 100644 --- a/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp +++ b/query/src/org/labkey/query/reports/view/reportsWebPartConfig.jsp @@ -1,202 +1,202 @@ -<% -/* - * Copyright (c) 2008-2019 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. - */ -%> -<%@ page import="org.apache.commons.lang3.BooleanUtils" %> -<%@ page import="org.apache.commons.lang3.StringUtils" %> -<%@ page import="org.labkey.api.data.Container" %> -<%@ page import="org.labkey.api.reports.Report" %> -<%@ page import="org.labkey.api.reports.report.ReportDescriptor" %> -<%@ page import="org.labkey.api.reports.report.ReportUrls" %> -<%@ page import="org.labkey.api.reports.report.view.ReportUtil" %> -<%@ page import="org.labkey.api.security.User" %> -<%@ page import="org.labkey.api.security.permissions.AdminPermission" %> -<%@ page import="org.labkey.api.util.PageFlowUtil" %> -<%@ page import="org.labkey.api.view.HttpView" %> -<%@ page import="org.labkey.api.view.JspView" %> -<%@ page import="org.labkey.api.view.Portal" %> -<%@ page import="org.labkey.api.view.ViewContext" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.LinkedHashMap" %> -<%@ page import="java.util.Map" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> - -<% - JspView me = HttpView.currentView(); - Portal.WebPart webPart = me.getModelBean(); - ViewContext context = getViewContext(); - - Map pm = webPart.getPropertyMap(); - - Map reportMap = new LinkedHashMap<>(); - ArrayList reportNames = new ArrayList<>(); - - ReportUtil.ReportFilter filter = new ReportUtil.DefaultReportFilter(); - Container c = getContainer(); - User u = getUser(); - boolean showHidden = c.hasPermission(u, AdminPermission.class); - - for (Report report : ReportUtil.getReportsIncludingInherited(c, u, null)) - { - if (!filter.accept(report, c, u) || (report.getDescriptor().isHidden() && !showHidden) || !report.isShowInReportsWebPart()) - continue; - - String reportName = report.getDescriptor().getReportName(); - if (!StringUtils.isEmpty(reportName)) - { - if (report.getDescriptor().isHidden()) - reportName = reportName + " (hidden)"; - reportMap.put(reportName, report.getDescriptor().getReportId().toString()); - reportNames.add(reportName); - } - } - reportNames.sort(String.CASE_INSENSITIVE_ORDER); - - String sectionName = Report.renderParam.showSection.name(); - String showTabs = Report.renderParam.showTabs.name(); -%> - - - - - - - - - - - - - - <% addHandler("showTabs", "click", "return onShowTabs(this.checked);"); %> - - - - - <% addHandler("showSection", "change", "return selectSection();"); %> - - - - - -
Web Part Title:">
Report or Chart: - <% addHandler("reportId", "change", "getSectionNames(this);"); %> - -
Show Tabs:<%=helpPopup("Show tabs", - "Some reports/charts may be rendered with multiple tabs showing. Select this option to only show the primary one.")%>>
Visible Report Sections:<%=helpPopup("Show Report sections", - "Some reports/charts contain multiple sections such as: images, text, console output. For these types of report, you can select which section(s) to " + - "display by selecting them from the list.")%>
-
- -
- - +<% +/* + * Copyright (c) 2008-2019 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. + */ +%> +<%@ page import="org.apache.commons.lang3.BooleanUtils" %> +<%@ page import="org.apache.commons.lang3.StringUtils" %> +<%@ page import="org.labkey.api.data.Container" %> +<%@ page import="org.labkey.api.reports.Report" %> +<%@ page import="org.labkey.api.reports.report.ReportDescriptor" %> +<%@ page import="org.labkey.api.reports.report.ReportUrls" %> +<%@ page import="org.labkey.api.reports.report.view.ReportUtil" %> +<%@ page import="org.labkey.api.security.User" %> +<%@ page import="org.labkey.api.security.permissions.AdminPermission" %> +<%@ page import="org.labkey.api.util.PageFlowUtil" %> +<%@ page import="org.labkey.api.view.HttpView" %> +<%@ page import="org.labkey.api.view.JspView" %> +<%@ page import="org.labkey.api.view.Portal" %> +<%@ page import="org.labkey.api.view.ViewContext" %> +<%@ page import="java.util.ArrayList" %> +<%@ page import="java.util.LinkedHashMap" %> +<%@ page import="java.util.Map" %> +<%@ page extends="org.labkey.api.jsp.JspBase" %> +<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> + +<% + JspView me = HttpView.currentView(); + Portal.WebPart webPart = me.getModelBean(); + ViewContext context = getViewContext(); + + Map pm = webPart.getPropertyMap(); + + Map reportMap = new LinkedHashMap<>(); + ArrayList reportNames = new ArrayList<>(); + + ReportUtil.ReportFilter filter = new ReportUtil.DefaultReportFilter(); + Container c = getContainer(); + User u = getUser(); + boolean showHidden = c.hasPermission(u, AdminPermission.class); + + for (Report report : ReportUtil.getReportsIncludingInherited(c, u, null)) + { + if (!filter.accept(report, c, u) || (report.getDescriptor().isHidden() && !showHidden) || !report.isShowInReportsWebPart()) + continue; + + String reportName = report.getDescriptor().getReportName(); + if (!StringUtils.isEmpty(reportName)) + { + if (report.getDescriptor().isHidden()) + reportName = reportName + " (hidden)"; + reportMap.put(reportName, report.getDescriptor().getReportId().toString()); + reportNames.add(reportName); + } + } + reportNames.sort(String.CASE_INSENSITIVE_ORDER); + + String sectionName = Report.renderParam.showSection.name(); + String showTabs = Report.renderParam.showTabs.name(); +%> + + + + + + + + + + + + + + <% addHandler("showTabs", "click", "return onShowTabs(this.checked);"); %> + + + + + <% addHandler("showSection", "change", "return selectSection();"); %> + + + + + +
Web Part Title:">
Report or Chart: + <% addHandler("reportId", "change", "getSectionNames(this);"); %> + +
Show Tabs:<%=helpPopup("Show tabs", + "Some reports/charts may be rendered with multiple tabs showing. Select this option to only show the primary one.")%>>
Visible Report Sections:<%=helpPopup("Show Report sections", + "Some reports/charts contain multiple sections such as: images, text, console output. For these types of report, you can select which section(s) to " + + "display by selecting them from the list.")%>
+
+ +
+ +