CE-878 add helpContent to widgetMetaData

This commit is contained in:
2024-02-27 19:39:46 -06:00
parent 217acc954a
commit 6919d9d810
5 changed files with 244 additions and 80 deletions

View File

@ -30,12 +30,14 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction; import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContent; import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContent;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpFormat; import com.kingsrook.qqq.backend.core.model.metadata.help.HelpFormat;
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole; import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
@ -109,6 +111,8 @@ public class QInstanceHelpContentManager
String processName = nameValuePairs.get("process"); String processName = nameValuePairs.get("process");
String fieldName = nameValuePairs.get("field"); String fieldName = nameValuePairs.get("field");
String sectionName = nameValuePairs.get("section"); String sectionName = nameValuePairs.get("section");
String widgetName = nameValuePairs.get("widget");
String slotName = nameValuePairs.get("slot");
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// build a help content meta-data object from the record // // build a help content meta-data object from the record //
@ -137,14 +141,37 @@ public class QInstanceHelpContentManager
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
if(StringUtils.hasContent(tableName)) if(StringUtils.hasContent(tableName))
{ {
QTableMetaData table = qInstance.getTable(tableName); processHelpContentForTable(key, tableName, sectionName, fieldName, roles, helpContent);
}
else if(StringUtils.hasContent(processName))
{
processHelpContentForProcess(key, processName, fieldName, roles, helpContent);
}
else if(StringUtils.hasContent(widgetName))
{
processHelpContentForWidget(key, widgetName, slotName, helpContent);
}
}
catch(Exception e)
{
LOG.warn("Error processing a helpContent record", e, logPair("id", record.getValue("id")));
}
}
/*******************************************************************************
**
*******************************************************************************/
private static void processHelpContentForTable(String key, String tableName, String sectionName, String fieldName, Set<HelpRole> roles, QHelpContent helpContent)
{
QTableMetaData table = QContext.getQInstance().getTable(tableName);
if(table == null) if(table == null)
{ {
LOG.info("Unrecognized table in help content", logPair("key", key)); LOG.info("Unrecognized table in help content", logPair("key", key));
return;
} }
else if(StringUtils.hasContent(fieldName))
if(StringUtils.hasContent(fieldName))
{ {
////////////////////////// //////////////////////////
// handle a table field // // handle a table field //
@ -153,10 +180,8 @@ public class QInstanceHelpContentManager
if(field == null) if(field == null)
{ {
LOG.info("Unrecognized table field in help content", logPair("key", key)); LOG.info("Unrecognized table field in help content", logPair("key", key));
return;
} }
else if(helpContent != null)
if(helpContent != null)
{ {
field.withHelpContent(helpContent); field.withHelpContent(helpContent);
} }
@ -174,10 +199,8 @@ public class QInstanceHelpContentManager
if(optionalSection.isEmpty()) if(optionalSection.isEmpty())
{ {
LOG.info("Unrecognized table section in help content", logPair("key", key)); LOG.info("Unrecognized table section in help content", logPair("key", key));
return;
} }
else if(helpContent != null)
if(helpContent != null)
{ {
optionalSection.get().withHelpContent(helpContent); optionalSection.get().withHelpContent(helpContent);
} }
@ -187,16 +210,20 @@ public class QInstanceHelpContentManager
} }
} }
} }
else if(StringUtils.hasContent(processName))
/*******************************************************************************
**
*******************************************************************************/
private static void processHelpContentForProcess(String key, String processName, String fieldName, Set<HelpRole> roles, QHelpContent helpContent)
{ {
QProcessMetaData process = qInstance.getProcess(processName); QProcessMetaData process = QContext.getQInstance().getProcess(processName);
if(process == null) if(process == null)
{ {
LOG.info("Unrecognized process in help content", logPair("key", key)); LOG.info("Unrecognized process in help content", logPair("key", key));
return;
} }
else if(StringUtils.hasContent(fieldName))
if(StringUtils.hasContent(fieldName))
{ {
//////////////////////////// ////////////////////////////
// handle a process field // // handle a process field //
@ -208,10 +235,8 @@ public class QInstanceHelpContentManager
if(optionalField.isEmpty()) if(optionalField.isEmpty())
{ {
LOG.info("Unrecognized process field in help content", logPair("key", key)); LOG.info("Unrecognized process field in help content", logPair("key", key));
return;
} }
else if(helpContent != null)
if(helpContent != null)
{ {
optionalField.get().withHelpContent(helpContent); optionalField.get().withHelpContent(helpContent);
} }
@ -221,10 +246,41 @@ public class QInstanceHelpContentManager
} }
} }
} }
}
catch(Exception e)
/*******************************************************************************
**
*******************************************************************************/
private static void processHelpContentForWidget(String key, String widgetName, String slotName, QHelpContent helpContent)
{ {
LOG.warn("Error processing a helpContent record", e, logPair("id", record.getValue("id"))); QWidgetMetaDataInterface widget = QContext.getQInstance().getWidget(widgetName);
if(!StringUtils.hasContent(slotName))
{
LOG.info("Missing slot name in help content", logPair("key", key));
}
else if(widget == null)
{
LOG.info("Unrecognized widget in help content", logPair("key", key));
}
else
{
Map<String, QHelpContent> widgetHelpContent = widget.getHelpContent();
if(widgetHelpContent == null)
{
widgetHelpContent = new HashMap<>();
}
if(helpContent != null)
{
widgetHelpContent.put(slotName, helpContent);
}
else
{
widgetHelpContent.remove(slotName);
}
widget.setHelpContent(widgetHelpContent);
} }
} }

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType; 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.code.QCodeReference;
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules; import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
@ -60,6 +61,8 @@ public class QWidgetMetaData implements QWidgetMetaDataInterface
protected Map<String, QIcon> icons; protected Map<String, QIcon> icons;
protected Map<String, QHelpContent> helpContent;
protected Map<String, Serializable> defaultValues = new LinkedHashMap<>(); protected Map<String, Serializable> defaultValues = new LinkedHashMap<>();
@ -687,4 +690,35 @@ public class QWidgetMetaData implements QWidgetMetaDataInterface
return (this); return (this);
} }
/*******************************************************************************
** Getter for helpContent
*******************************************************************************/
public Map<String, QHelpContent> getHelpContent()
{
return (this.helpContent);
}
/*******************************************************************************
** Setter for helpContent
*******************************************************************************/
public void setHelpContent(Map<String, QHelpContent> helpContent)
{
this.helpContent = helpContent;
}
/*******************************************************************************
** Fluent setter for helpContent
*******************************************************************************/
public QWidgetMetaData withHelpContent(Map<String, QHelpContent> helpContent)
{
this.helpContent = helpContent;
return (this);
}
} }

View File

@ -25,9 +25,11 @@ package com.kingsrook.qqq.backend.core.model.metadata.dashboard;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
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.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface; import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface;
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
import com.kingsrook.qqq.backend.core.model.metadata.permissions.MetaDataWithPermissionRules; import com.kingsrook.qqq.backend.core.model.metadata.permissions.MetaDataWithPermissionRules;
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules; import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
@ -38,6 +40,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRule
*******************************************************************************/ *******************************************************************************/
public interface QWidgetMetaDataInterface extends MetaDataWithPermissionRules, TopLevelMetaDataInterface public interface QWidgetMetaDataInterface extends MetaDataWithPermissionRules, TopLevelMetaDataInterface
{ {
QLogger LOG = QLogger.getLogger(QWidgetMetaDataInterface.class);
/******************************************************************************* /*******************************************************************************
** Getter for name ** Getter for name
*******************************************************************************/ *******************************************************************************/
@ -228,6 +232,23 @@ public interface QWidgetMetaDataInterface extends MetaDataWithPermissionRules, T
return (null); return (null);
} }
/*******************************************************************************
**
*******************************************************************************/
default Map<String, QHelpContent> getHelpContent()
{
return (null);
}
/*******************************************************************************
**
*******************************************************************************/
default void setHelpContent(Map<String, QHelpContent> helpContent)
{
LOG.debug("Setting help content in a widgetMetaData type that doesn't support it (because it didn't override the getter/setter)");
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/

View File

@ -31,6 +31,7 @@ import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
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.QWidgetMetaDataInterface; import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
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.help.QHelpContent;
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
@ -58,6 +59,7 @@ public class QFrontendWidgetMetaData
private boolean showExportButton = false; private boolean showExportButton = false;
protected Map<String, QIcon> icons; protected Map<String, QIcon> icons;
protected Map<String, QHelpContent> helpContent;
private final boolean hasPermission; private final boolean hasPermission;
@ -92,6 +94,8 @@ public class QFrontendWidgetMetaData
this.icons = qWidgetMetaData.getIcons(); this.icons = qWidgetMetaData.getIcons();
} }
this.helpContent = widgetMetaData.getHelpContent();
hasPermission = PermissionsHelper.hasWidgetPermission(actionInput, name); hasPermission = PermissionsHelper.hasWidgetPermission(actionInput, name);
} }
@ -259,4 +263,15 @@ public class QFrontendWidgetMetaData
{ {
return tooltip; return tooltip;
} }
/*******************************************************************************
** Getter for helpContent
**
*******************************************************************************/
public Map<String, QHelpContent> getHelpContent()
{
return helpContent;
}
} }

View File

@ -25,6 +25,7 @@ package com.kingsrook.qqq.backend.core.instances;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import com.kingsrook.qqq.backend.core.BaseTest; import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.actions.dashboard.PersonsByCreateDateBarChart;
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction; import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction; import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction; import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
@ -37,13 +38,16 @@ import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContent;
import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContentMetaDataProvider; import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContentMetaDataProvider;
import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContentRole; import com.kingsrook.qqq.backend.core.model.helpcontent.HelpContentRole;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole; import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent; import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpRole; import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpRole;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.core.utils.TestUtils; import com.kingsrook.qqq.backend.core.utils.TestUtils;
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.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/******************************************************************************* /*******************************************************************************
@ -183,6 +187,40 @@ class QInstanceHelpContentManagerTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testWidget() throws QException
{
/////////////////////////////////////
// get the instance from base test //
/////////////////////////////////////
QInstance qInstance = QContext.getQInstance();
new HelpContentMetaDataProvider().defineAll(qInstance, TestUtils.MEMORY_BACKEND_NAME, null);
//////////////////////////////////////////////////////////
// first, assert there's no help content on the section //
//////////////////////////////////////////////////////////
QWidgetMetaDataInterface widget = qInstance.getWidget(PersonsByCreateDateBarChart.class.getSimpleName());
assertTrue(CollectionUtils.nullSafeIsEmpty(widget.getHelpContent()));
HelpContent recordEntity = new HelpContent()
.withId(1)
.withKey("widget:" + widget.getName() + ";slot:label")
.withContent("i need somebody")
.withRole(HelpContentRole.ALL_SCREENS.getId());
new InsertAction().execute(new InsertInput(HelpContent.TABLE_NAME).withRecordEntity(recordEntity));
///////////////////////////////////////////////////////////////////////////////////////////////
// now - post-insert customizer should have automatically added help content to the instance //
///////////////////////////////////////////////////////////////////////////////////////////////
assertTrue(widget.getHelpContent().containsKey("label"));
assertEquals("i need somebody", widget.getHelpContent().get("label").getContent());
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/