mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Add optional additional validation to widget meta datas; implemented at least in part for ChildRecordListWidget
This commit is contained in:
@ -37,6 +37,8 @@ import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||
@ -51,12 +53,15 @@ import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChildRecordListData;
|
||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.AbstractWidgetMetaDataBuilder;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||
@ -83,7 +88,9 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
||||
.withIsCard(true)
|
||||
.withCodeReference(new QCodeReference(ChildRecordListRenderer.class))
|
||||
.withType(WidgetType.CHILD_RECORD_LIST.getType())
|
||||
.withDefaultValue("joinName", join.getName())));
|
||||
.withDefaultValue("joinName", join.getName())
|
||||
.withValidatorPlugin(new ChildRecordListWidgetValidator())
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@ -165,10 +172,10 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
||||
*******************************************************************************/
|
||||
public Builder withManageAssociationName(String manageAssociationName)
|
||||
{
|
||||
// todo - validate association name exists (on the table?)
|
||||
widgetMetaData.withDefaultValue("manageAssociationName", manageAssociationName);
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -321,4 +328,68 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private static class ChildRecordListWidgetValidator implements QInstanceValidatorPluginInterface<QWidgetMetaDataInterface>
|
||||
{
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void validate(QWidgetMetaDataInterface widgetMetaData, QInstance qInstance, QInstanceValidator qInstanceValidator)
|
||||
{
|
||||
String prefix = "Widget " + widgetMetaData.getName() + ": ";
|
||||
|
||||
//////////////////////////////////
|
||||
// make sure join name is given //
|
||||
//////////////////////////////////
|
||||
String joinName = ValueUtils.getValueAsString(CollectionUtils.nonNullMap(widgetMetaData.getDefaultValues()).get("joinName"));
|
||||
if(qInstanceValidator.assertCondition(StringUtils.hasContent(joinName), prefix + "defaultValue for joinName must be given"))
|
||||
{
|
||||
///////////////////////////
|
||||
// make sure join exists //
|
||||
///////////////////////////
|
||||
QJoinMetaData join = qInstance.getJoin(joinName);
|
||||
if(qInstanceValidator.assertCondition(join != null, prefix + "No join named " + joinName + " exists in the instance"))
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// if there's a manageAssociationName, make sure the table has that association //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
String manageAssociationName = ValueUtils.getValueAsString(widgetMetaData.getDefaultValues().get("manageAssociationName"));
|
||||
if(StringUtils.hasContent(manageAssociationName))
|
||||
{
|
||||
validateAssociationName(prefix, manageAssociationName, join, qInstance, qInstanceValidator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private void validateAssociationName(String prefix, String manageAssociationName, QJoinMetaData join, QInstance qInstance, QInstanceValidator qInstanceValidator)
|
||||
{
|
||||
///////////////////////////////////
|
||||
// make sure join's table exists //
|
||||
///////////////////////////////////
|
||||
QTableMetaData table = qInstance.getTable(join.getLeftTable());
|
||||
if(table == null)
|
||||
{
|
||||
qInstanceValidator.getErrors().add(prefix + "Unable to validate manageAssociationName, as table [" + join.getLeftTable() + "] on left-side table of join [" + join.getName() + "] does not exist.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CollectionUtils.nonNullList(table.getAssociations()).stream().noneMatch(a -> manageAssociationName.equals(a.getName())))
|
||||
{
|
||||
qInstanceValidator.getErrors().add(prefix + "an association named [" + manageAssociationName + "] does not exist on table [" + join.getLeftTable() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2008,6 +2008,11 @@ public class QInstanceValidator
|
||||
}
|
||||
}
|
||||
|
||||
if(widget.getValidatorPlugin() != null)
|
||||
{
|
||||
widget.getValidatorPlugin().validate(widget, qInstance, this);
|
||||
}
|
||||
|
||||
runPlugins(QWidgetMetaDataInterface.class, widget, qInstance);
|
||||
}
|
||||
);
|
||||
|
@ -30,6 +30,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceHelpContentManager;
|
||||
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
|
||||
@ -69,6 +70,7 @@ public class QWidgetMetaData implements QWidgetMetaDataInterface
|
||||
|
||||
protected Map<String, Serializable> defaultValues = new LinkedHashMap<>();
|
||||
|
||||
protected QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> validatorPlugin;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -764,4 +766,35 @@ public class QWidgetMetaData implements QWidgetMetaDataInterface
|
||||
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, listForSlot);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for validatorPlugin
|
||||
*******************************************************************************/
|
||||
public QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> getValidatorPlugin()
|
||||
{
|
||||
return (this.validatorPlugin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for validatorPlugin
|
||||
*******************************************************************************/
|
||||
public void setValidatorPlugin(QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> validatorPlugin)
|
||||
{
|
||||
this.validatorPlugin = validatorPlugin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for validatorPlugin
|
||||
*******************************************************************************/
|
||||
public QWidgetMetaData withValidatorPlugin(QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> validatorPlugin)
|
||||
{
|
||||
this.validatorPlugin = validatorPlugin;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface;
|
||||
@ -277,5 +278,13 @@ public interface QWidgetMetaDataInterface extends MetaDataWithPermissionRules, T
|
||||
qInstance.addWidget(this);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** let the widget include an instance validator plugin
|
||||
***************************************************************************/
|
||||
default QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> getValidatorPlugin()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public @interface ChildRecordListWidget
|
||||
{
|
||||
boolean enabled();
|
||||
|
||||
String label() default "";
|
||||
String label();
|
||||
|
||||
int maxRows() default 20;
|
||||
|
||||
|
Reference in New Issue
Block a user