diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DividerWidgetRenderer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DividerWidgetRenderer.java
new file mode 100644
index 00000000..4cc9a5f3
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DividerWidgetRenderer.java
@@ -0,0 +1,47 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2022. 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.actions.dashboard.widgets;
+
+
+import com.kingsrook.qqq.backend.core.actions.ActionHelper;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
+import com.kingsrook.qqq.backend.core.model.dashboard.widgets.DividerWidgetData;
+
+
+/*******************************************************************************
+ ** Generic widget for showing a divider
+ *******************************************************************************/
+public class DividerWidgetRenderer extends AbstractWidgetRenderer
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public RenderWidgetOutput render(RenderWidgetInput input) throws QException
+ {
+ ActionHelper.validateSession(input);
+ return (new RenderWidgetOutput(new DividerWidgetData()));
+ }
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java
index bca03c6c..b3d134ac 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java
@@ -69,9 +69,10 @@ public class ParentWidgetRenderer extends AbstractWidgetRenderer
/////////////////////////////////////////////////////////////
// handle any PVSs creating dropdown data for the frontend //
/////////////////////////////////////////////////////////////
- List>> pvsData = new ArrayList<>();
- List pvsLabels = new ArrayList<>();
- List pvsNames = new ArrayList<>();
+ List>> pvsData = new ArrayList<>();
+ List pvsLabels = new ArrayList<>();
+ List pvsNames = new ArrayList<>();
+ List missingRequiredSelections = new ArrayList<>();
for(ParentWidgetMetaData.DropdownData dropdownData : CollectionUtils.nonNullList(metaData.getDropdowns()))
{
String possibleValueSourceName = dropdownData.getPossibleValueSourceName();
@@ -81,7 +82,8 @@ public class ParentWidgetRenderer extends AbstractWidgetRenderer
// this looks complicated, but is just look for a label in the dropdown data and if found use it, //
// otherwise look for label in PVS and if found use that, otherwise just use the PVS name //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- pvsLabels.add(dropdownData.getLabel() != null ? dropdownData.getLabel() : (possibleValueSource.getLabel() != null ? possibleValueSource.getLabel() : possibleValueSourceName));
+ String pvsLabel = dropdownData.getLabel() != null ? dropdownData.getLabel() : (possibleValueSource.getLabel() != null ? possibleValueSource.getLabel() : possibleValueSourceName);
+ pvsLabels.add(pvsLabel);
pvsNames.add(possibleValueSourceName);
SearchPossibleValueSourceInput pvsInput = new SearchPossibleValueSourceInput(input.getInstance());
@@ -126,12 +128,37 @@ public class ParentWidgetRenderer extends AbstractWidgetRenderer
"label", possibleValue.getLabel()
));
}
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // because we know the dropdowns and what the field names will be when something is selected, we can make //
+ // sure that something has been selected, and if not, display a message that a selection needs made //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ if(dropdownData.getIsRequired())
+ {
+ if(!input.getQueryParams().containsKey(possibleValueSourceName) || !StringUtils.hasContent(input.getQueryParams().get(possibleValueSourceName)))
+ {
+ missingRequiredSelections.add(pvsLabel);
+ }
+ }
}
widgetData.setDropdownNameList(pvsNames);
widgetData.setDropdownLabelList(pvsLabels);
widgetData.setDropdownDataList(pvsData);
- widgetData.setChildWidgetNameList(metaData.getChildWidgetNameList());
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // if there are any missing required dropdowns, build up a message to display //
+ ////////////////////////////////////////////////////////////////////////////////
+ if(missingRequiredSelections.size() > 0)
+ {
+ StringBuilder sb = new StringBuilder("Please select a ").append(StringUtils.joinWithCommasAndAnd(missingRequiredSelections));
+ sb.append(" from the ").append(StringUtils.plural(missingRequiredSelections.size(), "dropdown", "dropdowns")).append(" above.");
+ widgetData.setDropdownNeedsSelectedText(sb.toString());
+ }
+ else
+ {
+ widgetData.setChildWidgetNameList(metaData.getChildWidgetNameList());
+ }
return (new RenderWidgetOutput(widgetData));
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/SearchPossibleValueSourceAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/SearchPossibleValueSourceAction.java
index f6490000..369785ed 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/SearchPossibleValueSourceAction.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/SearchPossibleValueSourceAction.java
@@ -161,7 +161,6 @@ public class SearchPossibleValueSourceAction
QQueryFilter queryFilter = new QQueryFilter();
queryFilter.setBooleanOperator(QQueryFilter.BooleanOperator.OR);
- queryInput.setFilter(queryFilter);
if(input.getIdList() != null)
{
@@ -207,11 +206,19 @@ public class SearchPossibleValueSourceAction
queryFilter.setOrderBys(possibleValueSource.getOrderByFields());
- // todo - default filter
-
// todo - skip & limit as params
queryInput.setLimit(250);
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // if given a default filter, make it the 'top level' filter and the one we just created a subfilter //
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ if(input.getDefaultQueryFilter() != null)
+ {
+ input.getDefaultQueryFilter().addSubFilter(queryFilter);
+ queryFilter = input.getDefaultQueryFilter();
+ }
+ queryInput.setFilter(queryFilter);
+
QueryOutput queryOutput = new QueryAction().execute(queryInput);
List ids = queryOutput.getRecords().stream().map(r -> r.getValue(table.getPrimaryKeyField())).toList();
List> qPossibleValues = possibleValueTranslator.buildTranslatedPossibleValueList(possibleValueSource, ids);
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/widgets/RenderWidgetInput.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/widgets/RenderWidgetInput.java
index a6a868e3..395c09f4 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/widgets/RenderWidgetInput.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/widgets/RenderWidgetInput.java
@@ -38,7 +38,7 @@ public class RenderWidgetInput extends AbstractActionInput
{
private QSession session;
private QWidgetMetaDataInterface widgetMetaData;
- private Map queryParams;
+ private Map queryParams = new HashMap<>();
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ChartData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ChartData.java
index d2ffc89c..6432d041 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ChartData.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ChartData.java
@@ -41,12 +41,11 @@ public class ChartData implements QWidget
}
*/
- private String title;
- private String description;
- private List colors;
- private Data chartData;
- private boolean isCurrency = false;
- private int height;
+ private String title;
+ private String description;
+ private Data chartData;
+ private boolean isCurrency = false;
+ private int height;
@@ -68,9 +67,12 @@ public class ChartData implements QWidget
setDescription(description);
setChartData(new ChartData.Data()
.withLabels(labels)
- .withDatasets(new ChartData.Data.Dataset()
- .withLabel(seriesLabel)
- .withData(data)));
+ .withDatasets(List.of(
+ new ChartData.Data.Dataset()
+ .withLabel(seriesLabel)
+ .withData(data)
+ ))
+ );
}
@@ -261,8 +263,8 @@ public class ChartData implements QWidget
*******************************************************************************/
public static class Data
{
- private List labels;
- private Dataset dataset;
+ private List labels;
+ private List datasets;
@@ -306,22 +308,7 @@ public class ChartData implements QWidget
*******************************************************************************/
public List getDatasets()
{
- if(dataset != null)
- {
- return List.of(dataset);
- }
- return List.of();
- }
-
-
-
- /*******************************************************************************
- ** Setter for datasets
- **
- *******************************************************************************/
- public void setDataset(Dataset dataset)
- {
- this.dataset = dataset;
+ return (datasets);
}
@@ -330,9 +317,9 @@ public class ChartData implements QWidget
** Fluent setter for datasets
**
*******************************************************************************/
- public Data withDatasets(Dataset datasets)
+ public Data withDatasets(List datasets)
{
- this.dataset = datasets;
+ this.datasets = datasets;
return (this);
}
@@ -344,8 +331,8 @@ public class ChartData implements QWidget
public static class Dataset
{
private String label;
- private String color;
private List data;
+ private String color;
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/DividerWidgetData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/DividerWidgetData.java
new file mode 100644
index 00000000..95e8295f
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/DividerWidgetData.java
@@ -0,0 +1,48 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2022. 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.dashboard.widgets;
+
+
+/*******************************************************************************
+ ** Model containing datastructure expected by frontend divider widget
+ **
+ *******************************************************************************/
+public class DividerWidgetData implements QWidget
+{
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public DividerWidgetData()
+ {
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for type
+ **
+ *******************************************************************************/
+ public String getType()
+ {
+ return WidgetType.DIVIDER.getType();
+ }
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ParentWidgetData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ParentWidgetData.java
index 87dd5399..af6600cd 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ParentWidgetData.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ParentWidgetData.java
@@ -27,7 +27,7 @@ import java.util.Map;
/*******************************************************************************
- ** Model containing datastructure expected by frontend stepper widget
+ ** Model containing datastructure expected by frontend parent widget
**
*******************************************************************************/
public class ParentWidgetData implements QWidget
@@ -43,6 +43,7 @@ public class ParentWidgetData implements QWidget
private List>> dropdownDataList;
private List childWidgetNameList;
+ private String dropdownNeedsSelectedText;
@@ -200,4 +201,38 @@ public class ParentWidgetData implements QWidget
return (this);
}
+
+
+ /*******************************************************************************
+ ** Getter for dropdownNeedsSelectedText
+ **
+ *******************************************************************************/
+ public String getDropdownNeedsSelectedText()
+ {
+ return dropdownNeedsSelectedText;
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for dropdownNeedsSelectedText
+ **
+ *******************************************************************************/
+ public void setDropdownNeedsSelectedText(String dropdownNeedsSelectedText)
+ {
+ this.dropdownNeedsSelectedText = dropdownNeedsSelectedText;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for dropdownNeedsSelectedText
+ **
+ *******************************************************************************/
+ public ParentWidgetData withDropdownNeedsSelectedText(String dropdownNeedsSelectedText)
+ {
+ this.dropdownNeedsSelectedText = dropdownNeedsSelectedText;
+ return (this);
+ }
+
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java
index 00ccee71..ebe1fb96 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java
@@ -30,6 +30,7 @@ public enum WidgetType
BAR_CHART("barChart"),
CHART("chart"),
CHILD_RECORD_LIST("childRecordList"),
+ DIVIDER("divider"),
GENERIC("generic"),
HORIZONTAL_BAR_CHART("horizontalBarChart"),
HTML("html"),
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/ParentWidgetMetaData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/ParentWidgetMetaData.java
index 589cc570..c1f51123 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/ParentWidgetMetaData.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/ParentWidgetMetaData.java
@@ -180,9 +180,10 @@ public class ParentWidgetMetaData extends QWidgetMetaData
*******************************************************************************/
public static class DropdownData
{
- private String possibleValueSourceName;
- private String foreignKeyFieldName;
- private String label;
+ private String possibleValueSourceName;
+ private String foreignKeyFieldName;
+ private String label;
+ private boolean isRequired;
@@ -286,6 +287,40 @@ public class ParentWidgetMetaData extends QWidgetMetaData
return (this);
}
+
+
+ /*******************************************************************************
+ ** Getter for isRequired
+ **
+ *******************************************************************************/
+ public boolean getIsRequired()
+ {
+ return isRequired;
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for isRequired
+ **
+ *******************************************************************************/
+ public void setIsRequired(boolean isRequired)
+ {
+ this.isRequired = isRequired;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for isRequired
+ **
+ *******************************************************************************/
+ public DropdownData withIsRequired(boolean isRequired)
+ {
+ this.isRequired = isRequired;
+ return (this);
+ }
+
}
}