Add support for omitFieldNames - by default, the join field, but also programmer-configurable.

This commit is contained in:
2025-05-23 12:14:26 -05:00
parent 37463c7676
commit 10fe644e60
3 changed files with 115 additions and 0 deletions

View File

@ -25,11 +25,13 @@ package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
import java.io.Serializable; import java.io.Serializable;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.google.gson.reflect.TypeToken;
import com.kingsrook.qqq.backend.core.actions.tables.CountAction; import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
import com.kingsrook.qqq.backend.core.actions.tables.GetAction; import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction; import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
@ -66,6 +68,7 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils;
import com.kingsrook.qqq.backend.core.utils.collections.MutableList;
import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.BooleanUtils;
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
@ -177,6 +180,18 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
return (this); return (this);
} }
/*******************************************************************************
**
*******************************************************************************/
public Builder withOmitFieldNames(List<String> omitFieldNames)
{
ArrayList<String> arrayList = CollectionUtils.useOrWrap(omitFieldNames, new TypeToken<>() {});
widgetMetaData.withDefaultValue("omitFieldNames", arrayList);
return (this);
}
} }
@ -197,6 +212,15 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
QTableMetaData rightTable = QContext.getQInstance().getTable(join.getRightTable()); QTableMetaData rightTable = QContext.getQInstance().getTable(join.getRightTable());
Map<String, Serializable> widgetMetaDataDefaultValues = input.getWidgetMetaData().getDefaultValues(); Map<String, Serializable> widgetMetaDataDefaultValues = input.getWidgetMetaData().getDefaultValues();
List<String> omitFieldNames = (List<String>) widgetMetaDataDefaultValues.get("omitFieldNames");
if(omitFieldNames == null)
{
omitFieldNames = new ArrayList<>();
}
else
{
omitFieldNames = new MutableList<>(omitFieldNames);
}
Integer maxRows = null; Integer maxRows = null;
if(StringUtils.hasContent(input.getQueryParams().get("maxRows"))) if(StringUtils.hasContent(input.getQueryParams().get("maxRows")))
@ -237,6 +261,7 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
for(JoinOn joinOn : join.getJoinOns()) for(JoinOn joinOn : join.getJoinOns())
{ {
filter.addCriteria(new QFilterCriteria(joinOn.getRightField(), QCriteriaOperator.EQUALS, List.of(primaryRecord.getValue(joinOn.getLeftField())))); filter.addCriteria(new QFilterCriteria(joinOn.getRightField(), QCriteriaOperator.EQUALS, List.of(primaryRecord.getValue(joinOn.getLeftField()))));
omitFieldNames.add(joinOn.getRightField());
} }
Serializable orderBy = widgetMetaDataDefaultValues.get("orderBy"); Serializable orderBy = widgetMetaDataDefaultValues.get("orderBy");
@ -278,6 +303,7 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset())); String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset()));
ChildRecordListData widgetData = new ChildRecordListData(widgetLabel, queryOutput, rightTable, tablePath, viewAllLink, totalRows); ChildRecordListData widgetData = new ChildRecordListData(widgetLabel, queryOutput, rightTable, tablePath, viewAllLink, totalRows);
widgetData.setOmitFieldNames(omitFieldNames);
if(BooleanUtils.isTrue(ValueUtils.getValueAsBoolean(input.getQueryParams().get("canAddChildRecord")))) if(BooleanUtils.isTrue(ValueUtils.getValueAsBoolean(input.getQueryParams().get("canAddChildRecord"))))
{ {

View File

@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.core.model.dashboard.widgets;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
@ -52,6 +53,7 @@ public class ChildRecordListData extends QWidgetData
private Map<String, Serializable> defaultValuesForNewChildRecords; private Map<String, Serializable> defaultValuesForNewChildRecords;
private Set<String> disabledFieldsForNewChildRecords; private Set<String> disabledFieldsForNewChildRecords;
private Map<String, String> defaultValuesForNewChildRecordsFromParentFields; private Map<String, String> defaultValuesForNewChildRecordsFromParentFields;
private List<String> omitFieldNames;
@ -555,6 +557,37 @@ public class ChildRecordListData extends QWidgetData
return (this); return (this);
} }
/*******************************************************************************
** Getter for omitFieldNames
*******************************************************************************/
public List<String> getOmitFieldNames()
{
return (this.omitFieldNames);
}
/*******************************************************************************
** Setter for omitFieldNames
*******************************************************************************/
public void setOmitFieldNames(List<String> omitFieldNames)
{
this.omitFieldNames = omitFieldNames;
}
/*******************************************************************************
** Fluent setter for omitFieldNames
*******************************************************************************/
public ChildRecordListData withOmitFieldNames(List<String> omitFieldNames)
{
this.omitFieldNames = omitFieldNames;
return (this);
}
} }

View File

@ -43,6 +43,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertTrue;
/******************************************************************************* /*******************************************************************************
@ -153,6 +154,61 @@ class ChildRecordListRendererTest extends BaseTest
assertThat(childRecordListData.getQueryOutput().getRecords()).hasSize(2); assertThat(childRecordListData.getQueryOutput().getRecords()).hasSize(2);
assertThat(childRecordListData.getQueryOutput().getRecords().get(0).getValueString("sku")).isEqualTo("BCD"); assertThat(childRecordListData.getQueryOutput().getRecords().get(0).getValueString("sku")).isEqualTo("BCD");
assertThat(childRecordListData.getQueryOutput().getRecords().get(1).getValueString("sku")).isEqualTo("ABC"); assertThat(childRecordListData.getQueryOutput().getRecords().get(1).getValueString("sku")).isEqualTo("ABC");
////////////////////////////////////////////////////////////////////////////////////////////////////
// order id, being the join field, should implicitly be omitted - and we asked to omit lineNumber //
////////////////////////////////////////////////////////////////////////////////////////////////////
assertTrue(childRecordListData.getOmitFieldNames().contains("orderId"));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testOmitFields() throws QException
{
QInstance qInstance = QContext.getQInstance();
QContext.getQSession().withSecurityKeyValue(TestUtils.SECURITY_KEY_TYPE_STORE_ALL_ACCESS, true);
QWidgetMetaData widget = ChildRecordListRenderer.widgetMetaDataBuilder(qInstance.getJoin("orderLineItem"))
.withLabel("Line Items")
.withOmitFieldNames(List.of("lineNumber"))
.getWidgetMetaData();
qInstance.addWidget(widget);
TestUtils.insertRecords(qInstance.getTable(TestUtils.TABLE_NAME_ORDER), List.of(
new QRecord().withValue("id", 1),
new QRecord().withValue("id", 2)
));
TestUtils.insertRecords(qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM), List.of(
new QRecord().withValue("orderId", 1).withValue("sku", "ABC").withValue("lineNumber", 2),
new QRecord().withValue("orderId", 1).withValue("sku", "BCD").withValue("lineNumber", 1),
new QRecord().withValue("orderId", 2).withValue("sku", "XYZ") // should not be found.
));
RenderWidgetInput input = new RenderWidgetInput();
input.setWidgetMetaData(widget);
input.setQueryParams(new HashMap<>(Map.of("id", "1")));
RenderWidgetAction renderWidgetAction = new RenderWidgetAction();
RenderWidgetOutput output = renderWidgetAction.execute(input);
ChildRecordListData childRecordListData = (ChildRecordListData) output.getWidgetData();
assertThat(childRecordListData.getChildTableMetaData()).hasFieldOrPropertyWithValue("name", TestUtils.TABLE_NAME_LINE_ITEM);
assertThat(childRecordListData.getQueryOutput().getRecords()).hasSize(2);
///////////////////////////////////////////////////////////////////////////
// we still get the data - it just includes a list of omitFieldNames now //
///////////////////////////////////////////////////////////////////////////
assertThat(childRecordListData.getQueryOutput().getRecords().get(0).getValue("orderId")).isNotNull();
////////////////////////////////////////////////////////////////////////////////////////////////////
// order id, being the join field, should implicitly be omitted - and we asked to omit lineNumber //
////////////////////////////////////////////////////////////////////////////////////////////////////
assertTrue(childRecordListData.getOmitFieldNames().contains("orderId"));
assertTrue(childRecordListData.getOmitFieldNames().contains("lineNumber"));
} }
} }