mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
CE-1107: added alert widget type and datepicker dropdown type
This commit is contained in:
@ -42,6 +42,7 @@ import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.QWidgetData;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.QWidgetData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.WidgetDropdownData;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.WidgetDropdownData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.WidgetDropdownType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue;
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
@ -72,80 +73,104 @@ public abstract class AbstractWidgetRenderer
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected boolean setupDropdowns(RenderWidgetInput input, QWidgetMetaData metaData, QWidgetData widgetData) throws QException
|
protected boolean setupDropdowns(RenderWidgetInput input, QWidgetMetaData metaData, QWidgetData widgetData) throws QException
|
||||||
{
|
{
|
||||||
List<List<Map<String, String>>> pvsData = new ArrayList<>();
|
List<List<Map<String, String>>> dataList = new ArrayList<>();
|
||||||
List<String> pvsLabels = new ArrayList<>();
|
List<String> labelList = new ArrayList<>();
|
||||||
List<String> pvsNames = new ArrayList<>();
|
List<String> nameList = new ArrayList<>();
|
||||||
List<String> missingRequiredSelections = new ArrayList<>();
|
List<String> missingRequiredSelections = new ArrayList<>();
|
||||||
for(WidgetDropdownData dropdownData : CollectionUtils.nonNullList(metaData.getDropdowns()))
|
for(WidgetDropdownData dropdownData : CollectionUtils.nonNullList(metaData.getDropdowns()))
|
||||||
{
|
{
|
||||||
String possibleValueSourceName = dropdownData.getPossibleValueSourceName();
|
if(WidgetDropdownType.DATE_PICKER.equals(dropdownData.getType()))
|
||||||
QPossibleValueSource possibleValueSource = input.getInstance().getPossibleValueSource(possibleValueSourceName);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
String pvsLabel = dropdownData.getLabel() != null ? dropdownData.getLabel() : (possibleValueSource.getLabel() != null ? possibleValueSource.getLabel() : possibleValueSourceName);
|
|
||||||
pvsLabels.add(pvsLabel);
|
|
||||||
pvsNames.add(possibleValueSourceName);
|
|
||||||
|
|
||||||
SearchPossibleValueSourceInput pvsInput = new SearchPossibleValueSourceInput();
|
|
||||||
pvsInput.setPossibleValueSourceName(possibleValueSourceName);
|
|
||||||
|
|
||||||
if(dropdownData.getForeignKeyFieldName() != null)
|
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
String name = dropdownData.getName();
|
||||||
// look for an id in the query params //
|
nameList.add(name);
|
||||||
////////////////////////////////////////
|
labelList.add(dropdownData.getLabel());
|
||||||
Integer id = null;
|
dataList.add(new ArrayList<>());
|
||||||
if(input.getQueryParams() != null && input.getQueryParams().containsKey("id") && StringUtils.hasContent(input.getQueryParams().get("id")))
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// sure that something has been selected, and if not, display a message that a selection needs made //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(dropdownData.getIsRequired())
|
||||||
{
|
{
|
||||||
id = Integer.parseInt(input.getQueryParams().get("id"));
|
if(!input.getQueryParams().containsKey(name) || !StringUtils.hasContent(input.getQueryParams().get(name)))
|
||||||
}
|
{
|
||||||
if(id != null)
|
missingRequiredSelections.add(dropdownData.getLabel());
|
||||||
{
|
}
|
||||||
pvsInput.setDefaultQueryFilter(new QQueryFilter().withCriteria(
|
|
||||||
new QFilterCriteria(
|
|
||||||
dropdownData.getForeignKeyFieldName(),
|
|
||||||
QCriteriaOperator.EQUALS,
|
|
||||||
id)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceAction().execute(pvsInput);
|
|
||||||
|
|
||||||
List<Map<String, String>> dropdownOptionList = new ArrayList<>();
|
|
||||||
pvsData.add(dropdownOptionList);
|
|
||||||
|
|
||||||
//////////////////////////////////////////
|
|
||||||
// sort results, dedupe, and add to map //
|
|
||||||
//////////////////////////////////////////
|
|
||||||
Set<String> exists = new HashSet<>();
|
|
||||||
output.getResults().removeIf(pvs -> !exists.add(pvs.getLabel()));
|
|
||||||
for(QPossibleValue<?> possibleValue : output.getResults())
|
|
||||||
{
|
{
|
||||||
dropdownOptionList.add(MapBuilder.of(
|
String possibleValueSourceName = dropdownData.getPossibleValueSourceName();
|
||||||
"id", String.valueOf(possibleValue.getId()),
|
if(possibleValueSourceName != null)
|
||||||
"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);
|
QPossibleValueSource possibleValueSource = input.getInstance().getPossibleValueSource(possibleValueSourceName);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
String pvsLabel = dropdownData.getLabel() != null ? dropdownData.getLabel() : (possibleValueSource.getLabel() != null ? possibleValueSource.getLabel() : possibleValueSourceName);
|
||||||
|
labelList.add(pvsLabel);
|
||||||
|
nameList.add(possibleValueSourceName);
|
||||||
|
|
||||||
|
SearchPossibleValueSourceInput pvsInput = new SearchPossibleValueSourceInput();
|
||||||
|
pvsInput.setPossibleValueSourceName(possibleValueSourceName);
|
||||||
|
|
||||||
|
if(dropdownData.getForeignKeyFieldName() != null)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// look for an id in the query params //
|
||||||
|
////////////////////////////////////////
|
||||||
|
Integer id = null;
|
||||||
|
if(input.getQueryParams() != null && input.getQueryParams().containsKey("id") && StringUtils.hasContent(input.getQueryParams().get("id")))
|
||||||
|
{
|
||||||
|
id = Integer.parseInt(input.getQueryParams().get("id"));
|
||||||
|
}
|
||||||
|
if(id != null)
|
||||||
|
{
|
||||||
|
pvsInput.setDefaultQueryFilter(new QQueryFilter().withCriteria(
|
||||||
|
new QFilterCriteria(
|
||||||
|
dropdownData.getForeignKeyFieldName(),
|
||||||
|
QCriteriaOperator.EQUALS,
|
||||||
|
id)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPossibleValueSourceOutput output = new SearchPossibleValueSourceAction().execute(pvsInput);
|
||||||
|
|
||||||
|
List<Map<String, String>> dropdownOptionList = new ArrayList<>();
|
||||||
|
dataList.add(dropdownOptionList);
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// sort results, dedupe, and add to map //
|
||||||
|
//////////////////////////////////////////
|
||||||
|
Set<String> exists = new HashSet<>();
|
||||||
|
output.getResults().removeIf(pvs -> !exists.add(pvs.getLabel()));
|
||||||
|
for(QPossibleValue<?> possibleValue : output.getResults())
|
||||||
|
{
|
||||||
|
dropdownOptionList.add(MapBuilder.of(
|
||||||
|
"id", String.valueOf(possibleValue.getId()),
|
||||||
|
"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.setDropdownNameList(nameList);
|
||||||
widgetData.setDropdownLabelList(pvsLabels);
|
widgetData.setDropdownLabelList(labelList);
|
||||||
widgetData.setDropdownDataList(pvsData);
|
widgetData.setDropdownDataList(dataList);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// if there are any missing required dropdowns, build up a message to display //
|
// if there are any missing required dropdowns, build up a message to display //
|
||||||
|
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.dashboard.widgets;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Model containing datastructure expected by frontend alert widget
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class AlertData extends QWidgetData
|
||||||
|
{
|
||||||
|
public enum AlertType
|
||||||
|
{
|
||||||
|
ERROR,
|
||||||
|
SUCCESS,
|
||||||
|
WARNING
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String html;
|
||||||
|
private AlertType alertType;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public AlertData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public AlertData(AlertType alertType, String html)
|
||||||
|
{
|
||||||
|
setHtml(html);
|
||||||
|
setAlertType(alertType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for type
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getType()
|
||||||
|
{
|
||||||
|
return WidgetType.ALERT.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for html
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getHtml()
|
||||||
|
{
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for html
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setHtml(String html)
|
||||||
|
{
|
||||||
|
this.html = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for html
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public AlertData withHtml(String html)
|
||||||
|
{
|
||||||
|
this.html = html;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for alertType
|
||||||
|
*******************************************************************************/
|
||||||
|
public AlertType getAlertType()
|
||||||
|
{
|
||||||
|
return (this.alertType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for alertType
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setAlertType(AlertType alertType)
|
||||||
|
{
|
||||||
|
this.alertType = alertType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for alertType
|
||||||
|
*******************************************************************************/
|
||||||
|
public AlertData withAlertType(AlertType alertType)
|
||||||
|
{
|
||||||
|
this.alertType = alertType;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,6 +27,7 @@ package com.kingsrook.qqq.backend.core.model.dashboard.widgets;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public enum WidgetType
|
public enum WidgetType
|
||||||
{
|
{
|
||||||
|
ALERT("alert"),
|
||||||
BAR_CHART("barChart"),
|
BAR_CHART("barChart"),
|
||||||
CHART("chart"),
|
CHART("chart"),
|
||||||
CHILD_RECORD_LIST("childRecordList"),
|
CHILD_RECORD_LIST("childRecordList"),
|
||||||
|
@ -28,6 +28,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.dashboard;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class WidgetDropdownData
|
public class WidgetDropdownData
|
||||||
{
|
{
|
||||||
|
private String name;
|
||||||
private String possibleValueSourceName;
|
private String possibleValueSourceName;
|
||||||
private String foreignKeyFieldName;
|
private String foreignKeyFieldName;
|
||||||
private String label;
|
private String label;
|
||||||
@ -44,6 +45,9 @@ public class WidgetDropdownData
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
private String labelForNullValue;
|
private String labelForNullValue;
|
||||||
|
|
||||||
|
private WidgetDropdownType type = WidgetDropdownType.POSSIBLE_VALUE_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for possibleValueSourceName
|
** Getter for possibleValueSourceName
|
||||||
@ -366,4 +370,65 @@ public class WidgetDropdownData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public WidgetDropdownType getType()
|
||||||
|
{
|
||||||
|
return (this.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setType(WidgetDropdownType type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public WidgetDropdownData withType(WidgetDropdownType type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return (this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for name
|
||||||
|
*******************************************************************************/
|
||||||
|
public WidgetDropdownData withName(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.model.metadata.dashboard;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Possible types for widget dropdowns
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public enum WidgetDropdownType
|
||||||
|
{
|
||||||
|
POSSIBLE_VALUE_SOURCE,
|
||||||
|
DATE_PICKER
|
||||||
|
}
|
Reference in New Issue
Block a user