diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportTableCustomizer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportTableCustomizer.java
new file mode 100644
index 00000000..f66a6313
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportTableCustomizer.java
@@ -0,0 +1,107 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.savedreports;
+
+
+import java.util.List;
+import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizerInterface;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.reporting.pivottable.PivotTableDefinition;
+import com.kingsrook.qqq.backend.core.model.actions.tables.QueryOrGetInputInterface;
+import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
+import com.kingsrook.qqq.backend.core.model.data.QRecord;
+import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.SavedReportToReportMetaDataAdapter;
+import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
+import com.kingsrook.qqq.backend.core.utils.StringUtils;
+import org.apache.commons.lang.BooleanUtils;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class SavedReportTableCustomizer implements TableCustomizerInterface
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public List postQuery(QueryOrGetInputInterface queryInput, List records) throws QException
+ {
+ for(QRecord record : CollectionUtils.nonNullList(records))
+ {
+ String queryFilterJson = record.getValueString("queryFilterJson");
+ String columnsJson = record.getValueString("columnsJson");
+ String pivotTableJson = record.getValueString("pivotTableJson");
+
+ if(StringUtils.hasContent(queryFilterJson))
+ {
+ try
+ {
+ QQueryFilter qQueryFilter = SavedReportToReportMetaDataAdapter.getQQueryFilter(queryFilterJson);
+ int criteriaCount = CollectionUtils.nonNullList(qQueryFilter.getCriteria()).size();
+ record.setDisplayValue("queryFilterJson", criteriaCount + " Filter" + StringUtils.plural(criteriaCount));
+ }
+ catch(Exception e)
+ {
+ record.setDisplayValue("queryFilterJson", "Invalid Filter...");
+ }
+ }
+
+ if(StringUtils.hasContent(columnsJson))
+ {
+ try
+ {
+ ReportColumns reportColumns = SavedReportToReportMetaDataAdapter.getReportColumns(columnsJson);
+ long columnCount = CollectionUtils.nonNullList(reportColumns.getColumns())
+ .stream().filter(rc -> BooleanUtils.isTrue(rc.getIsVisible()))
+ .count();
+
+ record.setDisplayValue("columnsJson", columnCount + " Column" + StringUtils.plural((int) columnCount));
+ }
+ catch(Exception e)
+ {
+ record.setDisplayValue("columnsJson", "Invalid Columns...");
+ }
+ }
+
+ if(StringUtils.hasContent(pivotTableJson))
+ {
+ try
+ {
+ PivotTableDefinition pivotTableDefinition = SavedReportToReportMetaDataAdapter.getPivotTableDefinition(pivotTableJson);
+ int rowCount = CollectionUtils.nonNullList(pivotTableDefinition.getRows()).size();
+ int columnCount = CollectionUtils.nonNullList(pivotTableDefinition.getColumns()).size();
+ int valueCount = CollectionUtils.nonNullList(pivotTableDefinition.getValues()).size();
+ record.setDisplayValue("pivotTableJson", rowCount + " Row" + StringUtils.plural(rowCount) + ", " + columnCount + " Column" + StringUtils.plural(columnCount) + ", and " + valueCount + " Value" + StringUtils.plural(valueCount));
+ }
+ catch(Exception e)
+ {
+ record.setDisplayValue("pivotTableJson", "Invalid Pivot Table...");
+ }
+ }
+ }
+
+ return (records);
+ }
+
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java
index 7f1f68ae..16d09754 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/savedreports/SavedReportsMetaDataProvider.java
@@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.savedreports;
import java.util.List;
import java.util.function.Consumer;
+import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.DefaultWidgetRenderer;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
@@ -153,10 +154,7 @@ public class SavedReportsMetaDataProvider
.withSection(new QFieldSection("hidden", new QIcon().withName("text_snippet"), Tier.T2, List.of("inputFieldsJson", "userId")).withIsHidden(true))
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate")));
- for(String jsonFieldName : List.of("queryFilterJson", "columnsJson", "inputFieldsJson", "pivotTableJson"))
- {
- table.getField(jsonFieldName).withFieldAdornment(new FieldAdornment(AdornmentType.CODE_EDITOR).withValue(AdornmentType.CodeEditorValues.languageMode("json")));
- }
+ table.withCustomizer(TableCustomizers.POST_QUERY_RECORD, new QCodeReference(SavedReportTableCustomizer.class));
if(backendDetailEnricher != null)
{
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java
index 3fc4282c..0d09967d 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/savedreports/SavedReportToReportMetaDataAdapter.java
@@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.core.processes.implementations.savedreports;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -73,6 +74,7 @@ public class SavedReportToReportMetaDataAdapter
private static Consumer jsonMapperCustomizer = om -> om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
/*******************************************************************************
**
*******************************************************************************/
@@ -95,7 +97,7 @@ public class SavedReportToReportMetaDataAdapter
QTableMetaData table = qInstance.getTable(savedReport.getTableName());
dataSource.setSourceTable(savedReport.getTableName());
- dataSource.setQueryFilter(JsonUtils.toObject(savedReport.getQueryFilterJson(), QQueryFilter.class, jsonMapperCustomizer));
+ dataSource.setQueryFilter(getQQueryFilter(savedReport.getQueryFilterJson()));
//////////////////////////
// set up the main view //
@@ -113,7 +115,7 @@ public class SavedReportToReportMetaDataAdapter
// map them to a list of QReportField objects //
// also keep track of what joinTables we find that we need to select //
///////////////////////////////////////////////////////////////////////////////////////////////
- ReportColumns columnsObject = JsonUtils.toObject(savedReport.getColumnsJson(), ReportColumns.class, jsonMapperCustomizer);
+ ReportColumns columnsObject = getReportColumns(savedReport.getColumnsJson());
List reportColumns = new ArrayList<>();
view.setColumns(reportColumns);
@@ -185,7 +187,7 @@ public class SavedReportToReportMetaDataAdapter
/////////////////////////////////////////
if(StringUtils.hasContent(savedReport.getPivotTableJson()))
{
- PivotTableDefinition pivotTableDefinition = JsonUtils.toObject(savedReport.getPivotTableJson(), PivotTableDefinition.class, jsonMapperCustomizer);
+ PivotTableDefinition pivotTableDefinition = getPivotTableDefinition(savedReport.getPivotTableJson());
QReportView pivotView = new QReportView();
reportMetaData.getViews().add(pivotView);
@@ -292,6 +294,36 @@ public class SavedReportToReportMetaDataAdapter
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public static PivotTableDefinition getPivotTableDefinition(String pivotTableJson) throws IOException
+ {
+ return JsonUtils.toObject(pivotTableJson, PivotTableDefinition.class, jsonMapperCustomizer);
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public static ReportColumns getReportColumns(String columnsJson) throws IOException
+ {
+ return JsonUtils.toObject(columnsJson, ReportColumns.class, jsonMapperCustomizer);
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public static QQueryFilter getQQueryFilter(String queryFilterJson) throws IOException
+ {
+ return JsonUtils.toObject(queryFilterJson, QQueryFilter.class, jsonMapperCustomizer);
+ }
+
+
+
/*******************************************************************************
**
*******************************************************************************/
@@ -328,7 +360,6 @@ public class SavedReportToReportMetaDataAdapter
-
/*******************************************************************************
**
*******************************************************************************/