Merge remote-tracking branch 'origin/QQQ-41-v-2-of-app-home-pages-dashboards-etc' into feature/QQQ-42-reports

This commit is contained in:
2022-09-19 13:52:54 -05:00
23 changed files with 2228 additions and 70 deletions

View File

@ -25,7 +25,7 @@ package com.kingsrook.qqq.backend.core.actions.dashboard;
import java.util.ArrayList;
import java.util.List;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.BarChart;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChartData;
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.session.QSession;
@ -45,7 +45,7 @@ public class PersonsByCreateDateBarChart extends AbstractWidgetRenderer
try
{
List<String> labels = new ArrayList<>();
List<Number> data = new ArrayList<>();
List<Number> data = new ArrayList<>();
labels.add("Jan. 2022");
data.add(17);
@ -62,7 +62,7 @@ public class PersonsByCreateDateBarChart extends AbstractWidgetRenderer
labels.add("May 2022");
data.add(64);
return (new BarChart("Persons created per Month", "Person records", labels, data));
return (new ChartData("Persons created per Month", null, "Person records", labels, data));
}
catch(Exception e)
{

View File

@ -23,7 +23,7 @@ package com.kingsrook.qqq.backend.core.actions.dashboard;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.BarChart;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChartData;
import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@ -43,11 +43,11 @@ class WidgetDataLoaderTest
void test() throws QException
{
Object widgetData = new WidgetDataLoader().execute(TestUtils.defineInstance(), TestUtils.getMockSession(), PersonsByCreateDateBarChart.class.getSimpleName());
assertThat(widgetData).isInstanceOf(BarChart.class);
BarChart barChart = (BarChart) widgetData;
assertEquals("barChart", barChart.getType());
assertThat(barChart.getTitle()).isNotBlank();
assertNotNull(barChart.getBarChartData());
assertThat(widgetData).isInstanceOf(ChartData.class);
ChartData chartData = (ChartData) widgetData;
assertEquals("barChart", chartData.getType());
assertThat(chartData.getTitle()).isNotBlank();
assertNotNull(chartData.getChartData());
}
}
}

View File

@ -30,7 +30,11 @@ import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.Test;
import static com.kingsrook.qqq.backend.core.utils.TestUtils.APP_NAME_GREETINGS;
import static com.kingsrook.qqq.backend.core.utils.TestUtils.APP_NAME_MISCELLANEOUS;
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;
@ -163,6 +167,35 @@ class QInstanceEnricherTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testGenerateAppSections()
{
QInstance qInstance = TestUtils.defineInstance();
new QInstanceEnricher().enrich(qInstance);
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");
assertEquals(2, qInstance.getApp(APP_NAME_GREETINGS).getSections().get(0).getProcesses().size(), "Section should have two processes");
assertEquals(qInstance.getApp(APP_NAME_GREETINGS).getName(), qInstance.getApp(APP_NAME_GREETINGS).getSections().get(0).getName(), "Section name should default to app's");
assertNotNull(qInstance.getApp(APP_NAME_PEOPLE).getSections());
assertEquals(1, qInstance.getApp(APP_NAME_PEOPLE).getSections().size(), "App should automatically have one section");
assertEquals(2, qInstance.getApp(APP_NAME_PEOPLE).getSections().get(0).getTables().size(), "Section should have two tables");
assertEquals(0, qInstance.getApp(APP_NAME_PEOPLE).getSections().get(0).getProcesses().size(), "Section should not have processes");
assertEquals(qInstance.getApp(APP_NAME_PEOPLE).getName(), qInstance.getApp(APP_NAME_PEOPLE).getSections().get(0).getName(), "Section name should default to app's");
assertNotNull(qInstance.getApp(APP_NAME_MISCELLANEOUS).getSections());
assertEquals(1, qInstance.getApp(APP_NAME_MISCELLANEOUS).getSections().size(), "App should automatically have one section");
assertEquals(1, qInstance.getApp(APP_NAME_MISCELLANEOUS).getSections().get(0).getTables().size(), "Section should have one table");
assertEquals(1, qInstance.getApp(APP_NAME_MISCELLANEOUS).getSections().get(0).getProcesses().size(), "Section should have one process");
assertEquals(qInstance.getApp(APP_NAME_MISCELLANEOUS).getName(), qInstance.getApp(APP_NAME_MISCELLANEOUS).getSections().get(0).getName(), "Section name should default to app's");
}
/*******************************************************************************
**
*******************************************************************************/
@ -175,12 +208,12 @@ class QInstanceEnricherTest
assertNull(table.getRecordLabelFormat());
qInstance = TestUtils.defineInstance();
table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields("firstName");
table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields("firstName");
new QInstanceEnricher().enrich(qInstance);
assertEquals("%s", table.getRecordLabelFormat());
qInstance = TestUtils.defineInstance();
table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields("firstName", "lastName");
table = qInstance.getTable("person").withRecordLabelFormat(null).withRecordLabelFields("firstName", "lastName");
new QInstanceEnricher().enrich(qInstance);
assertEquals("%s %s", table.getRecordLabelFormat());
}

View File

@ -41,13 +41,14 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeUsage;
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.layout.QAppSection;
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
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.tables.QFieldSection;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.TableAutomationAction;
import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.TableAutomationAction;
import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@ -575,6 +576,123 @@ class QInstanceValidatorTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testAppSectionsMissingName()
{
QAppMetaData app = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection(null, "Section 1", new QIcon("person"), List.of("test"), null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app), "Missing a name");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testAppSectionsMissingLabel()
{
QAppMetaData app = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("Section 1", null, new QIcon("person"), List.of("test"), null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app), "Missing a label");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testAppSectionsNoFields()
{
QAppMetaData app1 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of(), List.of()));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app1), "section1 does not have any children", "child test is not listed in any app sections");
QAppMetaData app2 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), null, null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app2), "section1 does not have any children", "child test is not listed in any app sections");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testAppSectionsUnrecognizedFieldName()
{
QAppMetaData app1 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of("test", "tset"), null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app1), "not a child of this app");
QAppMetaData app2 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of("test"), List.of("tset")));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app2), "not a child of this app");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testAppSectionsDuplicatedFieldName()
{
QAppMetaData app1 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of("test", "test"), null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app1), "more than once");
QAppMetaData app2 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of("test"), null))
.withSection(new QAppSection("section2", "Section 2", new QIcon("person"), List.of("test"), null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app2), "more than once");
QAppMetaData app3 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of("test"), List.of("test")));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app3), "more than once");
QAppMetaData app4 = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), null, List.of("test", "test")));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app4), "more than once");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testChildNotInAnySections()
{
QTableMetaData table = new QTableMetaData().withName("test")
.withBackendName(TestUtils.DEFAULT_BACKEND_NAME)
.withSection(new QFieldSection("section1", "Section 1", new QIcon("person"), Tier.T1, List.of("id")))
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
.withField(new QFieldMetaData("name", QFieldType.STRING));
assertValidationFailureReasons((qInstance) -> qInstance.addTable(table), "not listed in any field sections");
QAppMetaData app = new QAppMetaData().withName("test")
.withChild(new QTableMetaData().withName("tset"))
.withChild(new QTableMetaData().withName("test"))
.withSection(new QAppSection("section1", "Section 1", new QIcon("person"), List.of("test"), null));
assertValidationFailureReasons((qInstance) -> qInstance.addApp(app), "not listed in any app sections");
}
/*******************************************************************************
**
*******************************************************************************/
@ -825,6 +943,7 @@ class QInstanceValidatorTest
}
/*******************************************************************************
**
*******************************************************************************/