mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
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:
@ -40,4 +40,14 @@ public abstract class AbstractWidgetRenderer
|
||||
*******************************************************************************/
|
||||
public abstract Object render(QInstance qInstance, QSession session, QWidgetMetaDataInterface qWidgetMetaData) throws QException;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getWidgetName()
|
||||
{
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -102,9 +103,12 @@ public class MetaDataAction
|
||||
apps.put(entry.getKey(), new QFrontendAppMetaData(entry.getValue()));
|
||||
treeNodes.put(entry.getKey(), new AppTreeNode(entry.getValue()));
|
||||
|
||||
for(QAppChildMetaData child : entry.getValue().getChildren())
|
||||
if(CollectionUtils.nullSafeHasContents(entry.getValue().getChildren()))
|
||||
{
|
||||
apps.get(entry.getKey()).addChild(new AppTreeNode(child));
|
||||
for(QAppChildMetaData child : entry.getValue().getChildren())
|
||||
{
|
||||
apps.get(entry.getKey()).addChild(new AppTreeNode(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
metaDataOutput.setApps(apps);
|
||||
|
@ -36,7 +36,9 @@ 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.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.processes.QComponentType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData;
|
||||
@ -217,6 +219,11 @@ public class QInstanceEnricher
|
||||
{
|
||||
app.setLabel(nameToLabel(app.getName()));
|
||||
}
|
||||
|
||||
if(CollectionUtils.nullSafeIsEmpty(app.getSections()))
|
||||
{
|
||||
generateAppSections(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -535,6 +542,54 @@ public class QInstanceEnricher
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** If a app didn't have any sections, generate "sensible defaults"
|
||||
*******************************************************************************/
|
||||
private void generateAppSections(QAppMetaData app)
|
||||
{
|
||||
if(CollectionUtils.nullSafeIsEmpty(app.getChildren()))
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// assume this app is valid if it has no children, but surely it doesn't need any sections then. //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// create an identity section for the id and any fields in the record label //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
QAppSection defaultSection = new QAppSection(app.getName(), app.getLabel(), new QIcon("badge"), new ArrayList<>(), new ArrayList<>());
|
||||
|
||||
boolean foundNonAppChild = false;
|
||||
if(CollectionUtils.nullSafeHasContents(app.getChildren()))
|
||||
{
|
||||
for(QAppChildMetaData child : app.getChildren())
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// only tables and processes are allowed to be in sections at this time, apps //
|
||||
// might be children but not in sections so keep track if we find any non-app //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
if(child.getClass().equals(QTableMetaData.class))
|
||||
{
|
||||
defaultSection.getTables().add(child.getName());
|
||||
foundNonAppChild = true;
|
||||
}
|
||||
else if(child.getClass().equals(QProcessMetaData.class))
|
||||
{
|
||||
defaultSection.getProcesses().add(child.getName());
|
||||
foundNonAppChild = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(foundNonAppChild)
|
||||
{
|
||||
app.addSection(defaultSection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** If a table didn't have any sections, generate "sensible defaults"
|
||||
*******************************************************************************/
|
||||
|
@ -40,6 +40,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeUsage;
|
||||
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.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
||||
@ -213,7 +214,7 @@ public class QInstanceValidator
|
||||
{
|
||||
for(QFieldSection section : table.getSections())
|
||||
{
|
||||
validateSection(table, section, fieldNamesInSections);
|
||||
validateFieldSection(table, section, fieldNamesInSections);
|
||||
if(section.getTier().equals(Tier.T1))
|
||||
{
|
||||
assertCondition(tier1Section == null, "Table " + tableName + " has more than 1 section listed as Tier 1");
|
||||
@ -479,7 +480,7 @@ public class QInstanceValidator
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void validateSection(QTableMetaData table, QFieldSection section, Set<String> fieldNamesInSections)
|
||||
private void validateFieldSection(QTableMetaData table, QFieldSection section, Set<String> fieldNamesInSections)
|
||||
{
|
||||
assertCondition(StringUtils.hasContent(section.getName()), "Missing a name for field section in table " + table.getName() + ".");
|
||||
assertCondition(StringUtils.hasContent(section.getLabel()), "Missing a label for field section in table " + table.getLabel() + ".");
|
||||
@ -500,6 +501,42 @@ public class QInstanceValidator
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void validateAppSection(QAppMetaData app, QAppSection section, Set<String> childNamesInSections)
|
||||
{
|
||||
assertCondition(StringUtils.hasContent(section.getName()), "Missing a name for a section in app " + app.getName() + ".");
|
||||
assertCondition(StringUtils.hasContent(section.getLabel()), "Missing a label for a section in app " + app.getLabel() + ".");
|
||||
boolean hasTables = CollectionUtils.nullSafeHasContents(section.getTables());
|
||||
boolean hasProcesses = CollectionUtils.nullSafeHasContents(section.getProcesses());
|
||||
if(assertCondition(hasTables || hasProcesses, "App " + app.getName() + " section " + section.getName() + " does not have any children."))
|
||||
{
|
||||
if(hasTables)
|
||||
{
|
||||
for(String tableName : section.getTables())
|
||||
{
|
||||
assertCondition(app.getChildren().stream().anyMatch(c -> c.getName().equals(tableName)), "App " + app.getName() + " section " + section.getName() + " specifies table " + tableName + ", which is not a child of this app.");
|
||||
assertCondition(!childNamesInSections.contains(tableName), "App " + app.getName() + " has table " + tableName + " listed more than once in its sections.");
|
||||
|
||||
childNamesInSections.add(tableName);
|
||||
}
|
||||
}
|
||||
if(hasProcesses)
|
||||
{
|
||||
for(String processName : section.getProcesses())
|
||||
{
|
||||
assertCondition(app.getChildren().stream().anyMatch(c -> c.getName().equals(processName)), "App " + app.getName() + " section " + section.getName() + " specifies process " + processName + ", which is not a child of this app.");
|
||||
assertCondition(!childNamesInSections.contains(processName), "App " + app.getName() + " has process " + processName + " listed more than once in its sections.");
|
||||
|
||||
childNamesInSections.add(processName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -565,6 +602,29 @@ public class QInstanceValidator
|
||||
childNames.add(child.getName());
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// validate field sections in the table //
|
||||
//////////////////////////////////////////
|
||||
Set<String> childNamesInSections = new HashSet<>();
|
||||
if(app.getSections() != null)
|
||||
{
|
||||
for(QAppSection section : app.getSections())
|
||||
{
|
||||
validateAppSection(app, section, childNamesInSections);
|
||||
}
|
||||
}
|
||||
|
||||
if(CollectionUtils.nullSafeHasContents(app.getChildren()))
|
||||
{
|
||||
for(QAppChildMetaData child : app.getChildren())
|
||||
{
|
||||
if(!child.getClass().equals(QAppMetaData.class))
|
||||
{
|
||||
assertCondition(childNamesInSections.contains(child.getName()), "App " + appName + " child " + child.getName() + " is not listed in any app sections.");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -29,32 +29,34 @@ import java.util.List;
|
||||
** Model containing datastructure expected by frontend bar chart widget
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class BarChart implements QWidget
|
||||
public class ChartData implements QWidget
|
||||
{
|
||||
|
||||
/*
|
||||
type: "barChart",
|
||||
title: "Parcel Invoice Lines per Month",
|
||||
barChartData: {
|
||||
labels: ["Feb 22", "Mar 22", "Apr 22", "May 22", "Jun 22", "Jul 22", "Aug 22"],
|
||||
datasets: {label: "Parcel Invoice Lines", data: [50000, 22000, 11111, 22333, 40404, 9876, 2355]},
|
||||
},
|
||||
interface BarChartData{
|
||||
labels: string[];
|
||||
datasets: {
|
||||
label: string;
|
||||
data: number[];
|
||||
}[];
|
||||
}
|
||||
*/
|
||||
|
||||
private String title;
|
||||
private Data barChartData;
|
||||
private String description;
|
||||
private Data chartData;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public BarChart(String title, String seriesLabel, List<String> labels, List<Number> data)
|
||||
public ChartData(String title, String description, String seriesLabel, List<String> labels, List<Number> data)
|
||||
{
|
||||
setTitle(title);
|
||||
setBarChartData(new BarChart.Data()
|
||||
setDescription(description);
|
||||
setChartData(new ChartData.Data()
|
||||
.withLabels(labels)
|
||||
.withDatasets(new BarChart.Data.DataSet()
|
||||
.withDatasets(new ChartData.Data.Dataset()
|
||||
.withLabel(seriesLabel)
|
||||
.withData(data)));
|
||||
}
|
||||
@ -98,7 +100,7 @@ public class BarChart implements QWidget
|
||||
** Fluent setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public BarChart withTitle(String title)
|
||||
public ChartData withTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return (this);
|
||||
@ -107,34 +109,68 @@ public class BarChart implements QWidget
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for barChartData
|
||||
** Getter for description
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data getBarChartData()
|
||||
public String getDescription()
|
||||
{
|
||||
return barChartData;
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for barChartData
|
||||
** Setter for description
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setBarChartData(Data barChartData)
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.barChartData = barChartData;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for barChartData
|
||||
** Fluent setter for description
|
||||
**
|
||||
*******************************************************************************/
|
||||
public BarChart withBarChartData(Data barChartData)
|
||||
public ChartData withDescription(String description)
|
||||
{
|
||||
this.barChartData = barChartData;
|
||||
this.description = description;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for chartData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data getChartData()
|
||||
{
|
||||
return chartData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for chartData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setChartData(Data chartData)
|
||||
{
|
||||
this.chartData = chartData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for chartData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ChartData withChartData(Data chartData)
|
||||
{
|
||||
this.chartData = chartData;
|
||||
return (this);
|
||||
}
|
||||
|
||||
@ -146,7 +182,7 @@ public class BarChart implements QWidget
|
||||
public static class Data
|
||||
{
|
||||
private List<String> labels;
|
||||
private DataSet datasets;
|
||||
private Dataset dataset;
|
||||
|
||||
|
||||
|
||||
@ -188,9 +224,9 @@ public class BarChart implements QWidget
|
||||
** Getter for datasets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public DataSet getDatasets()
|
||||
public Dataset getDataset()
|
||||
{
|
||||
return datasets;
|
||||
return dataset;
|
||||
}
|
||||
|
||||
|
||||
@ -199,9 +235,9 @@ public class BarChart implements QWidget
|
||||
** Setter for datasets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setDatasets(DataSet datasets)
|
||||
public void setDataset(Dataset dataset)
|
||||
{
|
||||
this.datasets = datasets;
|
||||
this.dataset = dataset;
|
||||
}
|
||||
|
||||
|
||||
@ -210,9 +246,9 @@ public class BarChart implements QWidget
|
||||
** Fluent setter for datasets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data withDatasets(DataSet datasets)
|
||||
public Data withDatasets(Dataset datasets)
|
||||
{
|
||||
this.datasets = datasets;
|
||||
this.dataset = datasets;
|
||||
return (this);
|
||||
}
|
||||
|
||||
@ -221,9 +257,9 @@ public class BarChart implements QWidget
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class DataSet
|
||||
public static class Dataset
|
||||
{
|
||||
private String label;
|
||||
private String label;
|
||||
private List<Number> data;
|
||||
|
||||
|
||||
@ -254,7 +290,7 @@ public class BarChart implements QWidget
|
||||
** Fluent setter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public DataSet withLabel(String label)
|
||||
public Dataset withLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
return (this);
|
||||
@ -288,7 +324,7 @@ public class BarChart implements QWidget
|
||||
** Fluent setter for data
|
||||
**
|
||||
*******************************************************************************/
|
||||
public DataSet withData(List<Number> data)
|
||||
public Dataset withData(List<Number> data)
|
||||
{
|
||||
this.data = data;
|
||||
return (this);
|
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Model containing datastructure expected by frontend bar chart widget
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class LineChartData implements QWidget
|
||||
{
|
||||
/*
|
||||
export interface DefaultLineChartData
|
||||
{
|
||||
labels: string[]; // monday, tues...
|
||||
lineLabels: string[]; // axle, cdl...
|
||||
datasets: {
|
||||
label: string; // axle, cdl...
|
||||
color?: "primary" | "secondary" | "info" | "success" | "warning" | "error" | "light" | "dark";
|
||||
data: number[];
|
||||
}[];
|
||||
};
|
||||
*/
|
||||
|
||||
private String title;
|
||||
private Data chartData;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LineChartData()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LineChartData(String title, List<String> labels, List<String> lineLabels, List<Data.Dataset> datasets)
|
||||
{
|
||||
setTitle(title);
|
||||
setChartData(new LineChartData.Data()
|
||||
.withLabels(labels)
|
||||
.withLineLabels(lineLabels)
|
||||
.withDatasets(datasets));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return "lineChart";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LineChartData withTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for chartData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data getChartData()
|
||||
{
|
||||
return chartData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for chartData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setChartData(Data chartData)
|
||||
{
|
||||
this.chartData = chartData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for chartData
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LineChartData withChartData(Data chartData)
|
||||
{
|
||||
this.chartData = chartData;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class Data
|
||||
{
|
||||
private List<String> labels;
|
||||
private List<String> lineLabels;
|
||||
private List<Dataset> datasets;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for labels
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getLabels()
|
||||
{
|
||||
return labels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for labels
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLabels(List<String> labels)
|
||||
{
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for labels
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data withLabels(List<String> labels)
|
||||
{
|
||||
this.labels = labels;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for lineLabels
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getLineLabels()
|
||||
{
|
||||
return lineLabels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for lineLabels
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLineLabels(List<String> lineLabels)
|
||||
{
|
||||
this.lineLabels = lineLabels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for lineLabels
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data withLineLabels(List<String> lineLabels)
|
||||
{
|
||||
this.lineLabels = lineLabels;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for datasets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Dataset> getDatasets()
|
||||
{
|
||||
return datasets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for datasets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setDatasets(List<Dataset> datasets)
|
||||
{
|
||||
this.datasets = datasets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for datasets
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Data withDatasets(List<Dataset> datasets)
|
||||
{
|
||||
this.datasets = datasets;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class Dataset
|
||||
{
|
||||
private String label;
|
||||
private List<Number> data;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Dataset withLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for data
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Number> getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for data
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setData(List<Number> data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for data
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Dataset withData(List<Number> data)
|
||||
{
|
||||
this.data = data;
|
||||
return (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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 location widget
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class LocationData implements QWidget
|
||||
{
|
||||
private String imageUrl;
|
||||
private String title;
|
||||
private String description;
|
||||
private String footerText;
|
||||
private String location;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LocationData(String imageUrl, String title, String description, String location, String footerText)
|
||||
{
|
||||
this.imageUrl = imageUrl;
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.location = location;
|
||||
this.footerText = footerText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return "location";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for imageUrl
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getImageUrl()
|
||||
{
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for imageUrl
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setImageUrl(String imageUrl)
|
||||
{
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for imageUrl
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LocationData withImageUrl(String imageUrl)
|
||||
{
|
||||
this.imageUrl = imageUrl;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for description
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for description
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for description
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LocationData withDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for footerText
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getFooterText()
|
||||
{
|
||||
return footerText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for footerText
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setFooterText(String footerText)
|
||||
{
|
||||
this.footerText = footerText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for footerText
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LocationData withFooterText(String footerText)
|
||||
{
|
||||
this.footerText = footerText;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LocationData withTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return (this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for location
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for location
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLocation(String location)
|
||||
{
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for location
|
||||
**
|
||||
*******************************************************************************/
|
||||
public LocationData withLocation(String location)
|
||||
{
|
||||
this.location = location;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 bar chart widget
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class StatisticsData implements QWidget
|
||||
{
|
||||
/*
|
||||
interface BarChartData{
|
||||
labels: string[];
|
||||
datasets: {
|
||||
label: string;
|
||||
data: number[];
|
||||
}[];
|
||||
}
|
||||
*/
|
||||
|
||||
private String title;
|
||||
private int count;
|
||||
private Number percentageAmount;
|
||||
private String percentageLabel;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StatisticsData(String title, int count, Number percentageAmount, String percentageLabel)
|
||||
{
|
||||
this.title = title;
|
||||
this.count = count;
|
||||
this.percentageLabel = percentageLabel;
|
||||
this.percentageAmount = percentageAmount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return "statistics";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StatisticsData withTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for count
|
||||
**
|
||||
*******************************************************************************/
|
||||
public int getCount()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for count
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setCount(int count)
|
||||
{
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for count
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StatisticsData withCount(int count)
|
||||
{
|
||||
this.count = count;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for percentageAmount
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Number getPercentageAmount()
|
||||
{
|
||||
return percentageAmount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for percentageAmount
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setPercentageAmount(Number percentageAmount)
|
||||
{
|
||||
this.percentageAmount = percentageAmount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for percentageAmount
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StatisticsData withPercentageAmount(Number percentageAmount)
|
||||
{
|
||||
this.percentageAmount = percentageAmount;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for percentageLabel
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getPercentageLabel()
|
||||
{
|
||||
return percentageLabel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for percentageLabel
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setPercentageLabel(String percentageLabel)
|
||||
{
|
||||
this.percentageLabel = percentageLabel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for percentageLabel
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StatisticsData withPercentageLabel(String percentageLabel)
|
||||
{
|
||||
this.percentageLabel = percentageLabel;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Model containing datastructure expected by frontend bar chart widget
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class TableData implements QWidget
|
||||
{
|
||||
/*
|
||||
const carrierSpendData = {
|
||||
columns: [
|
||||
{Header: "carrier", accessor: "product", width: "55%"},
|
||||
{Header: "total YTD", accessor: "value"},
|
||||
{Header: "monthly average", accessor: "adsSpent", align: "center"},
|
||||
{Header: "service failures", accessor: "refunds", align: "center"},
|
||||
],
|
||||
|
||||
rows: [
|
||||
{
|
||||
product: <ProductCell image={axlehire} name="AxleHire" orders="921" />,
|
||||
value: <DefaultCell>$140,925</DefaultCell>,
|
||||
adsSpent: <DefaultCell>$24,531</DefaultCell>,
|
||||
refunds: <RefundsCell value={121} icon={{color: "success", name: "keyboard_arrow_up"}} />,
|
||||
},
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
private String title;
|
||||
private List<Column> columns;
|
||||
private List<Map<String, Object>> rows;
|
||||
private List<String> dropdownOptions;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TableData(String title, List<Column> columns, List<Map<String, Object>> rows, List<String> dropdownOptions)
|
||||
{
|
||||
setTitle(title);
|
||||
setColumns(columns);
|
||||
setRows(rows);
|
||||
setDropdownOptions(dropdownOptions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return "table";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for title
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TableData withTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for columns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Column> getColumns()
|
||||
{
|
||||
return columns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for columns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setColumns(List<Column> columns)
|
||||
{
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for columns
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TableData withColumns(List<Column> columns)
|
||||
{
|
||||
this.columns = columns;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for rows
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Map<String, Object>> getRows()
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for rows
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setRows(List<Map<String, Object>> rows)
|
||||
{
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for rows
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TableData withRows(List<Map<String, Object>> rows)
|
||||
{
|
||||
this.rows = rows;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for dropdownOptions
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getDropdownOptions()
|
||||
{
|
||||
return dropdownOptions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for dropdownOptions
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setDropdownOptions(List<String> dropdownOptions)
|
||||
{
|
||||
this.dropdownOptions = dropdownOptions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for dropdownOptions
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TableData withDropdownOptions(List<String> dropdownOptions)
|
||||
{
|
||||
this.dropdownOptions = dropdownOptions;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class Column
|
||||
{
|
||||
private String type;
|
||||
private String header;
|
||||
private String accessor;
|
||||
private String width;
|
||||
private String align;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Column(String type, String header, String accessor, String width, String align)
|
||||
{
|
||||
this.type = type;
|
||||
this.header = header;
|
||||
this.accessor = accessor;
|
||||
this.width = width;
|
||||
this.align = align;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for header
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getHeader()
|
||||
{
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for header
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setHeader(String header)
|
||||
{
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for accessor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getAccessor()
|
||||
{
|
||||
return accessor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for accessor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setAccessor(String accessor)
|
||||
{
|
||||
this.accessor = accessor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for width
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for width
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setWidth(String width)
|
||||
{
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for align
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getAlign()
|
||||
{
|
||||
return align;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for align
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setAlign(String align)
|
||||
{
|
||||
this.align = align;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** fluent setter for header
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Column withHeader(String header)
|
||||
{
|
||||
this.header = header;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** fluent setter for accessor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Column withAccessor(String accessor)
|
||||
{
|
||||
this.accessor = accessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** fluent setter for width
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Column withWidth(String width)
|
||||
{
|
||||
this.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** fluent setter for align
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Column withAlign(String align)
|
||||
{
|
||||
this.align = align;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** fluent setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Column withType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,10 +23,13 @@ package com.kingsrook.qqq.backend.core.model.metadata.frontend;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
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.utils.CollectionUtils;
|
||||
|
||||
|
||||
@ -39,12 +42,14 @@ public class QFrontendAppMetaData
|
||||
{
|
||||
private String name;
|
||||
private String label;
|
||||
|
||||
private List<AppTreeNode> children = new ArrayList<>();
|
||||
private List<String> widgets = new ArrayList<>();
|
||||
|
||||
private String iconName;
|
||||
|
||||
private List<String> widgets = new ArrayList<>();
|
||||
private List<AppTreeNode> children = new ArrayList<>();
|
||||
private Map<String, AppTreeNode> childMap = new HashMap<>();
|
||||
|
||||
private List<QAppSection> sections;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -64,6 +69,11 @@ public class QFrontendAppMetaData
|
||||
{
|
||||
this.widgets = appMetaData.getWidgets();
|
||||
}
|
||||
|
||||
if(CollectionUtils.nullSafeHasContents(appMetaData.getSections()))
|
||||
{
|
||||
this.sections = appMetaData.getSections();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -101,6 +111,17 @@ public class QFrontendAppMetaData
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for childMap
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, AppTreeNode> getChildMap()
|
||||
{
|
||||
return childMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for iconName
|
||||
**
|
||||
@ -132,6 +153,7 @@ public class QFrontendAppMetaData
|
||||
{
|
||||
children = new ArrayList<>();
|
||||
}
|
||||
childMap.put(childAppTreeNode.getName(), childAppTreeNode);
|
||||
children.add(childAppTreeNode);
|
||||
}
|
||||
|
||||
@ -145,4 +167,15 @@ public class QFrontendAppMetaData
|
||||
{
|
||||
return widgets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for sections
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QAppSection> getSections()
|
||||
{
|
||||
return sections;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.layout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -40,7 +41,9 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
private String parentAppName;
|
||||
private QIcon icon;
|
||||
|
||||
private List<String> widgets;
|
||||
private List<String> widgets;
|
||||
private List<QAppSection> sections;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -137,7 +140,13 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
*******************************************************************************/
|
||||
public void setChildren(List<QAppChildMetaData> children)
|
||||
{
|
||||
this.children = children;
|
||||
if(CollectionUtils.nullSafeHasContents(children))
|
||||
{
|
||||
for(QAppChildMetaData child : children)
|
||||
{
|
||||
addChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -176,7 +185,7 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
*******************************************************************************/
|
||||
public QAppMetaData withChildren(List<QAppChildMetaData> children)
|
||||
{
|
||||
this.children = children;
|
||||
setChildren(children);
|
||||
return (this);
|
||||
}
|
||||
|
||||
@ -205,6 +214,7 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for icon
|
||||
**
|
||||
@ -226,6 +236,7 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for icon
|
||||
**
|
||||
@ -238,7 +249,6 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for widgets
|
||||
**
|
||||
@ -260,6 +270,7 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for widgets
|
||||
**
|
||||
@ -270,4 +281,63 @@ public class QAppMetaData implements QAppChildMetaData
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for sections
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QAppSection> getSections()
|
||||
{
|
||||
return sections;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for sections
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setSections(List<QAppSection> sections)
|
||||
{
|
||||
this.sections = sections;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for sections
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppMetaData withSections(List<QAppSection> sections)
|
||||
{
|
||||
this.sections = sections;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addSection(QAppSection section)
|
||||
{
|
||||
if(this.sections == null)
|
||||
{
|
||||
this.sections = new ArrayList<>();
|
||||
}
|
||||
this.sections.add(section);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for sections
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppMetaData withSection(QAppSection section)
|
||||
{
|
||||
this.addSection(section);
|
||||
return (this);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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.layout;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** A section of apps/tables/processes - a logical grouping.
|
||||
*******************************************************************************/
|
||||
public class QAppSection
|
||||
{
|
||||
private String name;
|
||||
private String label;
|
||||
private QIcon icon;
|
||||
|
||||
private List<String> tables;
|
||||
private List<String> processes;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection(String name, String label, QIcon icon, List<String> tables, List<String> processes)
|
||||
{
|
||||
this.name = name;
|
||||
this.label = label;
|
||||
this.icon = icon;
|
||||
this.tables = tables;
|
||||
this.processes = processes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection withName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection withLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tables
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getTables()
|
||||
{
|
||||
return tables;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for tables
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTables(List<String> tables)
|
||||
{
|
||||
this.tables = tables;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for tables
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection withTables(List<String> tables)
|
||||
{
|
||||
this.tables = tables;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for processes
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<String> getProcesses()
|
||||
{
|
||||
return processes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for processes
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setProcesses(List<String> processes)
|
||||
{
|
||||
this.processes = processes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for processes
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection withProcesses(List<String> processes)
|
||||
{
|
||||
this.processes = processes;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for icon
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QIcon getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for icon
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setIcon(QIcon icon)
|
||||
{
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for icon
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QAppSection withIcon(QIcon icon)
|
||||
{
|
||||
this.icon = icon;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
191
qqq-dev-tools/intellij/live-templates/Kingsrook-Java.xml
Normal file
191
qqq-dev-tools/intellij/live-templates/Kingsrook-Java.xml
Normal file
@ -0,0 +1,191 @@
|
||||
<template name="addX" value="/******************************************************************************* ** *******************************************************************************/ public void add$TYPE$($TYPE$ $var$) { if(this.$list$ == null) { this.$list$ = new ArrayList<>(); } this.$list$.add($var$); }" description="write a method to add an X to a list" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="TYPE" expression="className()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="var" expression="suggestVariableName()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="list" expression="suggestVariableName()" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="afterAllMethod" value="/******************************************************************************* ** *******************************************************************************/ @AfterAll static void afterAll() { $END$ } " description="Write a junt afterAll method" toReformat="true" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="afterEachMethod" value="/******************************************************************************* ** *******************************************************************************/ @AfterEach void afterEach() { $END$ } " description="Write a junt afterEach method" toReformat="true" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="beforeAllMethod" value="/******************************************************************************* ** *******************************************************************************/ @BeforeAll static void beforeAll() { $END$ } " description="Write a junt beforeAll method" toReformat="true" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="beforeAndAfterEachMethod" value="/******************************************************************************* ** *******************************************************************************/ @BeforeEach @AfterEach void beforeAndAfterEach() { $END$ } " description="Write a junt beforeAndAfterEach method" toReformat="true" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="beforeEachMethod" value="/******************************************************************************* ** *******************************************************************************/ @BeforeEach void beforeEach() { $END$ } " description="Write a junt beforeEach method" toReformat="true" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="gs" value=" /******************************************************************************* ** Getter for $field$ ** *******************************************************************************/ public $fieldType$ get$fieldUcFirst$() { return $field$; } /******************************************************************************* ** Setter for $field$ ** *******************************************************************************/ public void set$fieldUcFirst$($fieldType$ $field$) { this.$field$ = $field$; } " description="Write a getter and setter" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="field" expression="completeSmart()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="fieldUcFirst" expression="capitalize(field)" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="fieldType" expression="typeOfVariable(field)" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="gsw" value=" /******************************************************************************* ** Getter for $field$ ** *******************************************************************************/ public $fieldType$ get$fieldUcFirst$() { return $field$; } /******************************************************************************* ** Setter for $field$ ** *******************************************************************************/ public void set$fieldUcFirst$($fieldType$ $field$) { this.$field$ = $field$; } /******************************************************************************* ** Fluent setter for $field$ ** *******************************************************************************/ public $thisClass$ with$fieldUcFirst$($fieldType$ $field$) { this.$field$ = $field$; return (this); } " description="Write a getter, setter, and fluent setter" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="field" expression="completeSmart()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="thisClass" expression="className()" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="fieldUcFirst" expression="capitalize(field)" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="fieldType" expression="typeOfVariable(field)" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="innerclass" value="/******************************************************************************* ** *******************************************************************************/ $ACCESS$ static class $NAME$ { $END$ }" description="Write an inner class" toReformat="true" toShortenFQNames="true">
|
||||
<variable name="ACCESS" expression="enum("public", "private", "protected")" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="NAME" expression="" defaultValue=""Foo"" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="javadoc" value="/******************************************************************************* ** $END$ *******************************************************************************/" description="Write a method or class header javadoc comment" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="list" value="List<$TYPE$> $var$ = new ArrayList<>();" description="List<T> list = new ArrayList<>();" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="TYPE" expression="className()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="var" expression="completeSmart()" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="main" value="/******************************************************************************* ** *******************************************************************************/ public static void main(String[] args) { $CLASS$ instance = new $CLASS$(); instance.run(); } /******************************************************************************* ** *******************************************************************************/ public void run() { try { $END$ } catch(Exception e) { e.printStackTrace(); } }" description="Write a main method (which will instantiate the current class and call a new run() method)" toReformat="true" toShortenFQNames="true">
|
||||
<variable name="CLASS" expression="fileNameWithoutExtension()" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="COMPLETION" value="false" />
|
||||
<option name="JAVA_CODE" value="true" />
|
||||
<option name="JAVA_COMMENT" value="false" />
|
||||
<option name="JAVA_EXPRESSION" value="false" />
|
||||
<option name="JAVA_STATEMENT" value="false" />
|
||||
<option name="JAVA_STRING" value="false" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="map" value="Map<$KEY$, $VALUE$> $var$ = new HashMap<>();" description="Map<K,V> m = new HashMap<>();" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="KEY" expression="className()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="VALUE" expression="className()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="var" expression="completeSmart()" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="method" value="/******************************************************************************* ** *******************************************************************************/ $ACCESS$ $TYPE$ $NAME$($ARGS$) { $TYPE$ rs = new $TYPE$(); $END$ return(rs); }" description="Write a method (that returns something)" toReformat="true" toShortenFQNames="true">
|
||||
<variable name="ACCESS" expression="enum("public", "private", "protected")" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="TYPE" expression="" defaultValue=""Object"" alwaysStopAt="true" />
|
||||
<variable name="NAME" expression="" defaultValue=""foo"" alwaysStopAt="true" />
|
||||
<variable name="ARGS" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="methodVoid" value="/******************************************************************************* ** *******************************************************************************/ $ACCESS$ void $NAME$($ARGS$) { $END$ }" description="Write a method (that returns void)" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="ACCESS" expression="enum("public", "private", "protected")" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="NAME" expression="" defaultValue=""foo"" alwaysStopAt="true" />
|
||||
<variable name="ARGS" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="new" value="$TYPE$ $INSTANCE$ = new $TYPE$($END$);" description="Create new instance" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="TYPE" expression="" defaultValue=""Object"" alwaysStopAt="true" />
|
||||
<variable name="INSTANCE" expression="camelCase(TYPE)" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="newal" value="new ArrayList<>()" description="new ArrayList<>()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="newhm" value="new HashMap<>()" description="new HashMap<>()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="newhs" value="new HashSet<>()" description="new LinkedList<>()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="newlh" value="new ListingHash<>()" description="new ListingHash<>()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="newlhm" value="new LinkedHashMap<>()" description="new LinkedHashMap<>()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="newll" value="new LinkedList<>()" description="new LinkedList<>()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="set" value="Set<$TYPE$> $var$ = new HashSet<>();" description="Set<T> s = new HashSet<>();" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="TYPE" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="var" expression="completeSmart()" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="singleton" value="private static $CLASS_NAME$ $INSTANCE$ = null; /******************************************************************************* ** Singleton constructor *******************************************************************************/ private $CLASS_NAME$() { } /******************************************************************************* ** Singleton accessor *******************************************************************************/ public static $CLASS_NAME$ getInstance() { if($INSTANCE$ == null) { $INSTANCE$ = new $CLASS_NAME$(); } return ($INSTANCE$); } " description="Create a singleton field, constructor, and accessor" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="CLASS_NAME" expression="className()" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="INSTANCE" expression="decapitalize(className())" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="tcp" value="try { $END$ } catch(Exception e) { e.printStackTrace(); }" description="try { } catch(Exception e) { e.printStackTrace() }" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="tcpr" value="try { $END$ } catch(Exception e) { e.printStackTrace(); throw(e); }" description="try { } catch(Exception e) { e.printStackTrace(); throw(e); }" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="tct" value="try { $END$ } catch(Exception e) { throw(new $THROW$("$MESSAGE$", e)); }" description="try { } catch(Exception e) { throw(new Exception("", e); }" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="THROW" expression="expectedType()" defaultValue=""Exception"" alwaysStopAt="true" />
|
||||
<variable name="MESSAGE" expression="" defaultValue=""Error"" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="testMethod" value="/******************************************************************************* ** *******************************************************************************/ @Test void test$NAME_SUFFIX$() { $END$ } " description="Write a test method" toReformat="true" toShortenFQNames="true">
|
||||
<variable name="NAME_SUFFIX" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="with" value="/******************************************************************************* ** Fluent setter for $field$ ** *******************************************************************************/ public $thisClass$ with$fieldUcFirst$($fieldType$ $field$) { set$fieldUcFirst$($field$); return (this); } " description="Write a fluent setter" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="field" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="thisClass" expression="className()" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="fieldUcFirst" expression="capitalize(field)" defaultValue="" alwaysStopAt="false" />
|
||||
<variable name="fieldType" expression="typeOfVariable(field)" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
54
qqq-dev-tools/intellij/live-templates/Kingsrook-SQL.xml
Normal file
54
qqq-dev-tools/intellij/live-templates/Kingsrook-SQL.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<template name="alterAddColumn" value="ALTER TABLE $TABLE$ ADD $COLUMN$ $TYPE$;" description="Write an ALTER TABLE SQL statement to add a column" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="TABLE" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="COLUMN" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="TYPE" expression="enum("INTEGER","VARCHAR(250)","BOOLEAN","DECIMAL(12,2)","DATE","TIMESTAMP")" defaultValue="INTEGER" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="SQL" value="true" />
|
||||
<option name="XML_TEXT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="alterAddIndex" value="ALTER TABLE $TABLE$ ADD INDEX $INDEX_NAME$ ($COLUMN$);" description="Write an ALTER TABLE SQL statement to add an index" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="TABLE" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="COLUMN" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="INDEX_NAME" expression="concat("i_", regularExpression(regularExpression(COLUMN, ",", "_"), " ", "")" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="SQL" value="true" />
|
||||
<option name="XML_TEXT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="changeSetCreateTable" value="<changeSet author="$USER$" id="$STORY$-$INDEX$"> <createTable tableName="$TABLE$"> <column autoIncrement="true" name="id" type="INTEGER"> <constraints nullable="false" primaryKey="true" primaryKeyName="$TABLE$_pkey"/> </column> <column defaultValueComputed="CURRENT_TIMESTAMP" name="create_date" type="TIMESTAMP"/> <column defaultValueComputed="CURRENT_TIMESTAMP" name="modify_date" type="TIMESTAMP"/> <column name="$END$" type=""/> </createTable> </changeSet>" description="Write a Liquibase createTable changeset" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="USER" expression="user()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="STORY" expression="fileNameWithoutExtension()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="INDEX" expression="" defaultValue=""1"" alwaysStopAt="true" />
|
||||
<variable name="TABLE" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="XML_TEXT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="changeSetCreateTableAndLoadData" value="<changeSet author="$USER$" id="$STORY$-$INDEX$"> <createTable tableName="$TABLE$"> <column autoIncrement="true" name="id" type="INTEGER"> <constraints nullable="false" primaryKey="true" primaryKeyName="$TABLE$_pkey"/> </column> <column defaultValueComputed="CURRENT_TIMESTAMP" name="create_date" type="TIMESTAMP"/> <column defaultValueComputed="CURRENT_TIMESTAMP" name="modify_date" type="TIMESTAMP"/> <column name="$END$" type=""/> </createTable> </changeSet> <changeSet author="$USER$" id="$STORY$-$NEXT_INDEX$"> <loadData file="src/main/resources/liquibase/data/$TABLE$.csv" tableName="$TABLE$" /> </changeSet>" description="Write 2 Liquibase changesets, to create a table and load its data" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="USER" expression="user()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="STORY" expression="fileNameWithoutExtension()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="INDEX" expression="" defaultValue=""1"" alwaysStopAt="true" />
|
||||
<variable name="TABLE" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="NEXT_INDEX" expression="groovyScript("try { return(Integer.parseInt(_1) + 1) } catch(Exception e) { return ''; }", INDEX)" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="XML_TEXT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="changeSetLoadData" value="<changeSet author="$USER$" id="$STORY$-$INDEX$"> <loadData file="src/main/resources/liquibase/data/$TABLE$.csv" tableName="$TABLE$" /> </changeSet>" description="Write a Liquibase loadData changeset" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="USER" expression="user()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="STORY" expression="fileNameWithoutExtension()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="INDEX" expression="" defaultValue=""1"" alwaysStopAt="true" />
|
||||
<variable name="TABLE" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="XML_TEXT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="changeSetSQL" value="<changeSet author="$USER$" id="$STORY$-$INDEX$"> <sql> $END$ </sql> </changeSet>" description="Write a Liquibase SQL changeset" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="USER" expression="user()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="STORY" expression="fileNameWithoutExtension()" defaultValue="" alwaysStopAt="true" />
|
||||
<variable name="INDEX" expression="" defaultValue="" alwaysStopAt="true" />
|
||||
<context>
|
||||
<option name="XML_TEXT" value="true" />
|
||||
</context>
|
||||
</template>
|
46
qqq-dev-tools/intellij/live-templates/QQQ.xml
Normal file
46
qqq-dev-tools/intellij/live-templates/QQQ.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<template name="declog" value="private static final Logger LOG = LogManager.getLogger($THIS_CLASS$.class);" description="Declare a logger object (LOG) for a class without one" toReformat="false" toShortenFQNames="true">
|
||||
<variable name="THIS_CLASS" expression="fileNameWithoutExtension()" defaultValue="" alwaysStopAt="false" />
|
||||
<context>
|
||||
<option name="JAVA_DECLARATION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qcount" value="CountInput countInput = new CountInput(qInstance); countInput.setSession(new QSession()); countInput.setTableName(tableName); CountOutput countOutput = new CountAction().execute(countInput); " description="Write code to execute a QQQ CountAction" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qdf" value=".withDisplayFormat(DisplayFormat.$END$)" description="QQQ field - .withDisplayFormat()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qdfcom" value=".withDisplayFormat(DisplayFormat.COMMAS)" description="QQQ field - .withDisplayFormat(COMMAS)" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qdfcur" value=".withDisplayFormat(DisplayFormat.CURRENCY)" description="QQQ field - .withDisplayFormat(CURRENCY)" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qinsert" value="InsertInput insertInput = new InsertInput(qInstance); insertInput.setSession(new QSession()); insertInput.setTableName(tableName); insertInput.setRecords($END$); InsertOutput insertOutput = new InsertAction().execute(insertInput); " description="Write code to execute a QQQ InsertAction" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qlab" value=".withLabel("$END$")" description="QQQ meta data objects - .withLabel()" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_EXPRESSION" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qquery" value="QueryInput queryInput = new QueryInput(qInstance); queryInput.setSession(new QSession()); queryInput.setTableName(tableName); QueryOutput queryOutput = new QueryAction().execute(queryInput); " description="Write code to execute a QQQ QueryAction" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
||||
<template name="qupdate" value="UpdateInput updateInput = new UpdateInput($END$); updateInput.setSession(); updateInput.setTableName(); updateInput.setRecords(); UpdateOutput updateOutput = new UpdateAction().execute(updateInput); " description="Write code to execute a QQQ UpdateAction" toReformat="false" toShortenFQNames="true">
|
||||
<context>
|
||||
<option name="JAVA_STATEMENT" value="true" />
|
||||
</context>
|
||||
</template>
|
14
qqq-dev-tools/intellij/live-templates/README.md
Normal file
14
qqq-dev-tools/intellij/live-templates/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
## Usage
|
||||
You can add these live templates to your IntelliJ as follows:
|
||||
- Get the contents of one or more files on your clipboard
|
||||
- e.g., `cat Kingsrook-SQL.xml | pbcopy`
|
||||
- IntelliJ > Preferences > Editor > Live Templates
|
||||
- Select the Template Group that you want to put them in
|
||||
- Recommended that you use a group whose name matches the file name you're loading from
|
||||
- You may need to create a new one group via the + button
|
||||
- Right-click on the Template Group and choose Paste.
|
||||
|
||||
## Publishing
|
||||
From IntelliJ > Preferences > Editor > Live Templates, right-click
|
||||
on one or more Live Templates to copy it - paste it into an XML file.
|
||||
|
@ -26,7 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.actions.dashboard.AbstractWidgetRenderer;
|
||||
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;
|
||||
@ -46,7 +46,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);
|
||||
@ -63,7 +63,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)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.actions.dashboard.AbstractWidgetRenderer;
|
||||
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;
|
||||
@ -89,7 +89,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)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ package com.kingsrook.sampleapp.dashboard.widgets;
|
||||
|
||||
|
||||
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.session.QSession;
|
||||
import com.kingsrook.sampleapp.SampleMetaDataProvider;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
/*******************************************************************************
|
||||
** Unit test for PersonsByCreateDateBarChart
|
||||
*******************************************************************************/
|
||||
class PersonsByCreateDateBarChartTest
|
||||
class PersonsByCreateDateChartTestData
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
@ -45,11 +45,11 @@ class PersonsByCreateDateBarChartTest
|
||||
void test() throws QException
|
||||
{
|
||||
Object widgetData = new PersonsByCreateDateBarChart().render(SampleMetaDataProvider.defineInstance(), new QSession(), null);
|
||||
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("chartData", chartData.getType());
|
||||
assertThat(chartData.getTitle()).isNotBlank();
|
||||
assertNotNull(chartData.getChartData());
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user