mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Auto-adorn PVS tables with link-to-record; change query to fetch instants, not LocalDateTimes
This commit is contained in:
@ -34,12 +34,16 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppChildMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppSection;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSourceType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QComponentType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||
@ -73,12 +77,24 @@ public class QInstanceEnricher
|
||||
{
|
||||
private static final Logger LOG = LogManager.getLogger(QInstanceEnricher.class);
|
||||
|
||||
private final QInstance qInstance;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void enrich(QInstance qInstance)
|
||||
public QInstanceEnricher(QInstance qInstance)
|
||||
{
|
||||
this.qInstance = qInstance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void enrich()
|
||||
{
|
||||
if(qInstance.getTables() != null)
|
||||
{
|
||||
@ -210,6 +226,61 @@ public class QInstanceEnricher
|
||||
{
|
||||
field.setLabel(nameToLabel(field.getName()));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// if this field has a possibleValueSource //
|
||||
// and that PVS exists in the instance //
|
||||
// and it's a table-type PVS and the table name is set //
|
||||
// and it's a valid table in the instant, and the table is in some app //
|
||||
// and the field doesn't have a LINK adornment //
|
||||
// then add a link-to-record-from-table adornment to the field. //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
if(StringUtils.hasContent(field.getPossibleValueSourceName()))
|
||||
{
|
||||
QPossibleValueSource possibleValueSource = qInstance.getPossibleValueSource(field.getPossibleValueSourceName());
|
||||
if(possibleValueSource != null)
|
||||
{
|
||||
String tableName = possibleValueSource.getTableName();
|
||||
if(QPossibleValueSourceType.TABLE.equals(possibleValueSource.getType()) && StringUtils.hasContent(tableName))
|
||||
{
|
||||
if(qInstance.getTable(tableName) != null && doesAnyAppHaveTable(tableName))
|
||||
{
|
||||
if(field.getAdornments() == null || field.getAdornments().stream().noneMatch(a -> AdornmentType.LINK.equals(a.getType())))
|
||||
{
|
||||
field.withFieldAdornment(new FieldAdornment().withType(AdornmentType.LINK)
|
||||
.withValue(AdornmentType.LinkValues.TO_RECORD_FROM_TABLE, tableName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean doesAnyAppHaveTable(String tableName)
|
||||
{
|
||||
if(qInstance.getApps() != null)
|
||||
{
|
||||
for(QAppMetaData app : qInstance.getApps().values())
|
||||
{
|
||||
if(app.getChildren() != null)
|
||||
{
|
||||
for(QAppChildMetaData child : app.getChildren())
|
||||
{
|
||||
if(child instanceof QTableMetaData && tableName.equals(child.getName()))
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,7 +94,7 @@ public class QInstanceValidator
|
||||
// before validation, enrich the object (e.g., to fill in values that the user doesn't have to //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO - possible point of customization (use a different enricher, or none, or pass it options).
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
@ -43,7 +43,8 @@ public enum AdornmentType
|
||||
*******************************************************************************/
|
||||
public interface LinkValues
|
||||
{
|
||||
String TARGET = "target";
|
||||
String TARGET = "target";
|
||||
String TO_RECORD_FROM_TABLE = "toRecordFromTable";
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,9 +25,13 @@ package com.kingsrook.qqq.backend.core.instances;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
|
||||
@ -39,6 +43,7 @@ import static com.kingsrook.qqq.backend.core.utils.TestUtils.APP_NAME_PEOPLE;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -59,7 +64,7 @@ class QInstanceEnricherTest
|
||||
QTableMetaData personTable = qInstance.getTable("person");
|
||||
personTable.setLabel(null);
|
||||
assertNull(personTable.getLabel());
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertEquals("Person", personTable.getLabel());
|
||||
}
|
||||
|
||||
@ -79,7 +84,7 @@ class QInstanceEnricherTest
|
||||
personTable.setName(null);
|
||||
assertNull(personTable.getLabel());
|
||||
assertNull(personTable.getName());
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertNull(personTable.getLabel());
|
||||
assertNull(personTable.getName());
|
||||
}
|
||||
@ -97,7 +102,7 @@ class QInstanceEnricherTest
|
||||
QFieldMetaData idField = qInstance.getTable("person").getField("id");
|
||||
idField.setLabel(null);
|
||||
assertNull(idField.getLabel());
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertEquals("Id", idField.getLabel());
|
||||
}
|
||||
|
||||
@ -118,7 +123,7 @@ class QInstanceEnricherTest
|
||||
.withFieldNames(new ArrayList<>(personTable.getFields().keySet()))
|
||||
));
|
||||
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertEquals("Test", personTable.getSections().get(0).getLabel());
|
||||
}
|
||||
|
||||
@ -198,7 +203,7 @@ class QInstanceEnricherTest
|
||||
void testGenerateAppSections()
|
||||
{
|
||||
QInstance qInstance = TestUtils.defineInstance();
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertNotNull(qInstance.getApp(APP_NAME_GREETINGS).getSections());
|
||||
assertEquals(1, qInstance.getApp(APP_NAME_GREETINGS).getSections().size(), "App should automatically have one section");
|
||||
assertEquals(0, qInstance.getApp(APP_NAME_GREETINGS).getSections().get(0).getTables().size(), "Section should not have tables");
|
||||
@ -228,18 +233,57 @@ class QInstanceEnricherTest
|
||||
{
|
||||
QInstance qInstance = TestUtils.defineInstance();
|
||||
QTableMetaData table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields(new ArrayList<>());
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertNull(table.getRecordLabelFormat());
|
||||
|
||||
qInstance = TestUtils.defineInstance();
|
||||
table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields("firstName");
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertEquals("%s", table.getRecordLabelFormat());
|
||||
|
||||
qInstance = TestUtils.defineInstance();
|
||||
table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields("firstName", "lastName");
|
||||
new QInstanceEnricher().enrich(qInstance);
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertEquals("%s %s", table.getRecordLabelFormat());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testAddTablePvsAdornment()
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// first make sure the adornment doesn't get added for favoriteShapeId, because it isn't in any apps //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
QInstance qInstance = TestUtils.defineInstance();
|
||||
QTableMetaData personTable = qInstance.getTable("person");
|
||||
QFieldMetaData favoriteShapeId = personTable.getField("favoriteShapeId");
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertNull(favoriteShapeId.getAdornments());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// then put shape table in an app, re-run, and see it get adorned //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
QInstance qInstance = TestUtils.defineInstance();
|
||||
QTableMetaData shapeTable = qInstance.getTable(TestUtils.TABLE_NAME_SHAPE);
|
||||
QAppMetaData miscApp = qInstance.getApp(APP_NAME_MISCELLANEOUS);
|
||||
miscApp.addChild(shapeTable);
|
||||
|
||||
QTableMetaData personTable = qInstance.getTable("person");
|
||||
QFieldMetaData favoriteShapeId = personTable.getField("favoriteShapeId");
|
||||
new QInstanceEnricher(qInstance).enrich();
|
||||
assertNotNull(favoriteShapeId.getAdornments());
|
||||
Optional<FieldAdornment> optionalAdornment = favoriteShapeId.getAdornments().stream().filter(a -> a.getType().equals(AdornmentType.LINK)).findFirst();
|
||||
assertTrue(optionalAdornment.isPresent());
|
||||
FieldAdornment adornment = optionalAdornment.get();
|
||||
assertEquals("shape", adornment.getValues().get(AdornmentType.LinkValues.TO_RECORD_FROM_TABLE));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf
|
||||
}
|
||||
case DATE_TIME:
|
||||
{
|
||||
return (QueryManager.getLocalDateTime(resultSet, i));
|
||||
return (QueryManager.getInstant(resultSet, i));
|
||||
}
|
||||
case BOOLEAN:
|
||||
{
|
||||
|
@ -231,7 +231,8 @@ public class QJavalinProcessHandler
|
||||
if(userFacingException != null)
|
||||
{
|
||||
LOG.info("User-facing exception in process", userFacingException);
|
||||
resultForCaller.put("error", userFacingException.getMessage()); // todo - put this somewhere else (make error an object w/ user-facing and/or other error?)
|
||||
resultForCaller.put("error", userFacingException.getMessage());
|
||||
resultForCaller.put("userFacingError", userFacingException.getMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user