mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Merged dev into feature/pom-version-fixing
This commit is contained in:
@ -79,6 +79,19 @@ commands:
|
|||||||
- ~/.m2
|
- ~/.m2
|
||||||
key: v1-dependencies-{{ checksum "pom.xml" }}
|
key: v1-dependencies-{{ checksum "pom.xml" }}
|
||||||
|
|
||||||
|
check_middleware_api_versions:
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- v1-dependencies-{{ checksum "pom.xml" }}
|
||||||
|
- run:
|
||||||
|
name: Build and Run ValidateApiVersions
|
||||||
|
command: |
|
||||||
|
mvn -s .circleci/mvn-settings.xml -T4 install -DskipTests
|
||||||
|
mvn -s .circleci/mvn-settings.xml -pl qqq-middleware-javalin package appassembler:assemble -DskipTests
|
||||||
|
qqq-middleware-javalin/target/appassembler/bin/ValidateApiVersions -r $(pwd)
|
||||||
|
|
||||||
mvn_jar_deploy:
|
mvn_jar_deploy:
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
@ -130,6 +143,7 @@ jobs:
|
|||||||
## - localstack/startup
|
## - localstack/startup
|
||||||
- install_java17
|
- install_java17
|
||||||
- mvn_verify
|
- mvn_verify
|
||||||
|
- check_middleware_api_versions
|
||||||
|
|
||||||
mvn_deploy:
|
mvn_deploy:
|
||||||
executor: localstack/default
|
executor: localstack/default
|
||||||
@ -137,6 +151,7 @@ jobs:
|
|||||||
## - localstack/startup
|
## - localstack/startup
|
||||||
- install_java17
|
- install_java17
|
||||||
- mvn_verify
|
- mvn_verify
|
||||||
|
- check_middleware_api_versions
|
||||||
- mvn_jar_deploy
|
- mvn_jar_deploy
|
||||||
|
|
||||||
publish_asciidoc:
|
publish_asciidoc:
|
||||||
|
1
pom.xml
1
pom.xml
@ -36,6 +36,7 @@
|
|||||||
<module>qqq-backend-module-rdbms</module>
|
<module>qqq-backend-module-rdbms</module>
|
||||||
<module>qqq-backend-module-mongodb</module>
|
<module>qqq-backend-module-mongodb</module>
|
||||||
<module>qqq-language-support-javascript</module>
|
<module>qqq-language-support-javascript</module>
|
||||||
|
<module>qqq-openapi</module>
|
||||||
<module>qqq-middleware-picocli</module>
|
<module>qqq-middleware-picocli</module>
|
||||||
<module>qqq-middleware-javalin</module>
|
<module>qqq-middleware-javalin</module>
|
||||||
<module>qqq-middleware-lambda</module>
|
<module>qqq-middleware-lambda</module>
|
||||||
|
@ -23,11 +23,11 @@ package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
|
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.AlertData;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.AlertData;
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.metadata;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** a default implementation of MetaDataFilterInterface, that allows all the things
|
||||||
|
*******************************************************************************/
|
||||||
|
public class AllowAllMetaDataFilter implements MetaDataFilterInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowTable(MetaDataInput input, QTableMetaData table)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowProcess(MetaDataInput input, QProcessMetaData process)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowReport(MetaDataInput input, QReportMetaData report)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowApp(MetaDataInput input, QAppMetaData app)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowWidget(MetaDataInput input, QWidgetMetaDataInterface widget)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -28,13 +28,18 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionCheckResult;
|
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionCheckResult;
|
||||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
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.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendAppMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendAppMetaData;
|
||||||
@ -49,6 +54,7 @@ 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.reporting.QReportMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.memoization.Memoization;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -57,6 +63,12 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class MetaDataAction
|
public class MetaDataAction
|
||||||
{
|
{
|
||||||
|
private static final QLogger LOG = QLogger.getLogger(MetaDataAction.class);
|
||||||
|
|
||||||
|
private static Memoization<QInstance, MetaDataFilterInterface> metaDataFilterMemoization = new Memoization<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -64,10 +76,10 @@ public class MetaDataAction
|
|||||||
{
|
{
|
||||||
ActionHelper.validateSession(metaDataInput);
|
ActionHelper.validateSession(metaDataInput);
|
||||||
|
|
||||||
// todo pre-customization - just get to modify the request?
|
MetaDataOutput metaDataOutput = new MetaDataOutput();
|
||||||
MetaDataOutput metaDataOutput = new MetaDataOutput();
|
Map<String, AppTreeNode> treeNodes = new LinkedHashMap<>();
|
||||||
|
|
||||||
Map<String, AppTreeNode> treeNodes = new LinkedHashMap<>();
|
MetaDataFilterInterface filter = getMetaDataFilter();
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
// map tables to frontend metadata //
|
// map tables to frontend metadata //
|
||||||
@ -78,6 +90,11 @@ public class MetaDataAction
|
|||||||
String tableName = entry.getKey();
|
String tableName = entry.getKey();
|
||||||
QTableMetaData table = entry.getValue();
|
QTableMetaData table = entry.getValue();
|
||||||
|
|
||||||
|
if(!filter.allowTable(metaDataInput, table))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, table);
|
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, table);
|
||||||
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
||||||
{
|
{
|
||||||
@ -102,6 +119,11 @@ public class MetaDataAction
|
|||||||
String processName = entry.getKey();
|
String processName = entry.getKey();
|
||||||
QProcessMetaData process = entry.getValue();
|
QProcessMetaData process = entry.getValue();
|
||||||
|
|
||||||
|
if(!filter.allowProcess(metaDataInput, process))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, process);
|
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, process);
|
||||||
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
||||||
{
|
{
|
||||||
@ -122,6 +144,11 @@ public class MetaDataAction
|
|||||||
String reportName = entry.getKey();
|
String reportName = entry.getKey();
|
||||||
QReportMetaData report = entry.getValue();
|
QReportMetaData report = entry.getValue();
|
||||||
|
|
||||||
|
if(!filter.allowReport(metaDataInput, report))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, report);
|
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, report);
|
||||||
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
||||||
{
|
{
|
||||||
@ -142,6 +169,11 @@ public class MetaDataAction
|
|||||||
String widgetName = entry.getKey();
|
String widgetName = entry.getKey();
|
||||||
QWidgetMetaDataInterface widget = entry.getValue();
|
QWidgetMetaDataInterface widget = entry.getValue();
|
||||||
|
|
||||||
|
if(!filter.allowWidget(metaDataInput, widget))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, widget);
|
PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, widget);
|
||||||
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
if(permissionResult.equals(PermissionCheckResult.DENY_HIDE))
|
||||||
{
|
{
|
||||||
@ -174,9 +206,19 @@ public class MetaDataAction
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
apps.put(appName, new QFrontendAppMetaData(app, metaDataOutput));
|
if(!filter.allowApp(metaDataInput, app))
|
||||||
treeNodes.put(appName, new AppTreeNode(app));
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////
|
||||||
|
// build the frontend-app meta-data //
|
||||||
|
//////////////////////////////////////
|
||||||
|
QFrontendAppMetaData frontendAppMetaData = new QFrontendAppMetaData(app, metaDataOutput);
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// add children (if they're permitted) //
|
||||||
|
/////////////////////////////////////////
|
||||||
if(CollectionUtils.nullSafeHasContents(app.getChildren()))
|
if(CollectionUtils.nullSafeHasContents(app.getChildren()))
|
||||||
{
|
{
|
||||||
for(QAppChildMetaData child : app.getChildren())
|
for(QAppChildMetaData child : app.getChildren())
|
||||||
@ -190,9 +232,42 @@ public class MetaDataAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apps.get(appName).addChild(new AppTreeNode(child));
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the child was filtered away, so it isn't in its corresponding map, then don't include it here //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(child instanceof QTableMetaData table && !tables.containsKey(table.getName()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(child instanceof QProcessMetaData process && !processes.containsKey(process.getName()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(child instanceof QReportMetaData report && !reports.containsKey(report.getName()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(child instanceof QAppMetaData childApp && !apps.containsKey(childApp.getName()))
|
||||||
|
{
|
||||||
|
// continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
frontendAppMetaData.addChild(new AppTreeNode(child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the app ended up having no children, then discard it //
|
||||||
|
// todo - i think this was wrong, because it didn't take into account ... something nested maybe... //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(CollectionUtils.nullSafeIsEmpty(frontendAppMetaData.getChildren()) && CollectionUtils.nullSafeIsEmpty(frontendAppMetaData.getWidgets()))
|
||||||
|
{
|
||||||
|
// LOG.debug("Discarding empty app", logPair("name", frontendAppMetaData.getName()));
|
||||||
|
// continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
apps.put(appName, frontendAppMetaData);
|
||||||
|
treeNodes.put(appName, new AppTreeNode(app));
|
||||||
}
|
}
|
||||||
metaDataOutput.setApps(apps);
|
metaDataOutput.setApps(apps);
|
||||||
|
|
||||||
@ -228,6 +303,33 @@ public class MetaDataAction
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private MetaDataFilterInterface getMetaDataFilter()
|
||||||
|
{
|
||||||
|
return metaDataFilterMemoization.getResult(QContext.getQInstance(), i ->
|
||||||
|
{
|
||||||
|
MetaDataFilterInterface filter = null;
|
||||||
|
QCodeReference metaDataFilterReference = QContext.getQInstance().getMetaDataFilter();
|
||||||
|
if(metaDataFilterReference != null)
|
||||||
|
{
|
||||||
|
filter = QCodeLoader.getAdHoc(MetaDataFilterInterface.class, metaDataFilterReference);
|
||||||
|
LOG.debug("Using new meta-data filter of type: " + filter.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filter == null)
|
||||||
|
{
|
||||||
|
filter = new AllowAllMetaDataFilter();
|
||||||
|
LOG.debug("Using new default (allow-all) meta-data filter");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (filter);
|
||||||
|
}).orElseThrow(() -> new QRuntimeException("Error getting metaDataFilter"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.metadata;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public interface MetaDataFilterInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
boolean allowTable(MetaDataInput input, QTableMetaData table);
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
boolean allowProcess(MetaDataInput input, QProcessMetaData process);
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
boolean allowReport(MetaDataInput input, QReportMetaData report);
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
boolean allowApp(MetaDataInput input, QAppMetaData app);
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
boolean allowWidget(MetaDataInput input, QWidgetMetaDataInterface widget);
|
||||||
|
|
||||||
|
}
|
@ -40,6 +40,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReferenceLambda;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData;
|
||||||
@ -257,11 +258,20 @@ public class RunBackendStepAction
|
|||||||
{
|
{
|
||||||
runBackendStepOutput.seedFromRequest(runBackendStepInput);
|
runBackendStepOutput.seedFromRequest(runBackendStepInput);
|
||||||
|
|
||||||
Class<?> codeClass = Class.forName(code.getName());
|
Object codeObject;
|
||||||
Object codeObject = codeClass.getConstructor().newInstance();
|
if(code instanceof QCodeReferenceLambda<?> qCodeReferenceLambda)
|
||||||
|
{
|
||||||
|
codeObject = qCodeReferenceLambda.getLambda();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Class<?> codeClass = Class.forName(code.getName());
|
||||||
|
codeObject = codeClass.getConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
if(!(codeObject instanceof BackendStep backendStepCodeObject))
|
if(!(codeObject instanceof BackendStep backendStepCodeObject))
|
||||||
{
|
{
|
||||||
throw (new QException("The supplied code [" + codeClass.getName() + "] is not an instance of BackendStep"));
|
throw (new QException("The supplied codeReference [" + code + "] is not a reference to a BackendStep"));
|
||||||
}
|
}
|
||||||
|
|
||||||
backendStepCodeObject.run(runBackendStepInput, runBackendStepOutput);
|
backendStepCodeObject.run(runBackendStepInput, runBackendStepOutput);
|
||||||
|
@ -28,6 +28,7 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
|
||||||
@ -58,6 +59,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaD
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStateMachineStep;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.basepull.BasepullConfiguration;
|
import com.kingsrook.qqq.backend.core.processes.implementations.basepull.BasepullConfiguration;
|
||||||
@ -134,90 +136,11 @@ public class RunProcessAction
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String lastStepName = runProcessInput.getStartAfterStep();
|
switch(Objects.requireNonNull(process.getStepFlow(), "Process [" + process.getName() + "] has a null stepFlow."))
|
||||||
|
|
||||||
STEP_LOOP:
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
case LINEAR -> runLinearStepLoop(process, processState, stateKey, runProcessInput, runProcessOutput);
|
||||||
// always refresh the step list - as any step that runs can modify it (in the process state). //
|
case STATE_MACHINE -> runStateMachineStep(runProcessInput.getStartAfterStep(), process, processState, stateKey, runProcessInput, runProcessOutput, 0);
|
||||||
// this is why we don't do a loop over the step list - as we'd get ConcurrentModificationExceptions. //
|
default -> throw (new QException("Unhandled process step flow: " + process.getStepFlow()));
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
List<QStepMetaData> stepList = getAvailableStepList(processState, process, lastStepName);
|
|
||||||
if(stepList.isEmpty())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStepMetaData step = stepList.get(0);
|
|
||||||
lastStepName = step.getName();
|
|
||||||
|
|
||||||
if(step instanceof QFrontendStepMetaData frontendStep)
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
// Handle what to do with frontend steps, per request setting //
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
switch(runProcessInput.getFrontendStepBehavior())
|
|
||||||
{
|
|
||||||
case BREAK ->
|
|
||||||
{
|
|
||||||
LOG.trace("Breaking process [" + process.getName() + "] at frontend step (as requested by caller): " + step.getName());
|
|
||||||
processFrontendStepFieldDefaultValues(processState, frontendStep);
|
|
||||||
processFrontendComponents(processState, frontendStep);
|
|
||||||
processState.setNextStepName(step.getName());
|
|
||||||
break STEP_LOOP;
|
|
||||||
}
|
|
||||||
case SKIP ->
|
|
||||||
{
|
|
||||||
LOG.trace("Skipping frontend step [" + step.getName() + "] in process [" + process.getName() + "] (as requested by caller)");
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// much less error prone in case this code changes in the future... //
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// noinspection UnnecessaryContinue
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case FAIL ->
|
|
||||||
{
|
|
||||||
LOG.trace("Throwing error for frontend step [" + step.getName() + "] in process [" + process.getName() + "] (as requested by caller)");
|
|
||||||
throw (new QException("Failing process at step " + step.getName() + " (as requested, to fail on frontend steps)"));
|
|
||||||
}
|
|
||||||
default -> throw new IllegalStateException("Unexpected value: " + runProcessInput.getFrontendStepBehavior());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(step instanceof QBackendStepMetaData backendStepMetaData)
|
|
||||||
{
|
|
||||||
///////////////////////
|
|
||||||
// Run backend steps //
|
|
||||||
///////////////////////
|
|
||||||
LOG.debug("Running backend step [" + step.getName() + "] in process [" + process.getName() + "]");
|
|
||||||
RunBackendStepOutput runBackendStepOutput = runBackendStep(runProcessInput, process, runProcessOutput, stateKey, backendStepMetaData, process, processState);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// if the step returned an override lastStepName, use that to determine how we proceed //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
if(runBackendStepOutput.getOverrideLastStepName() != null)
|
|
||||||
{
|
|
||||||
LOG.debug("Process step [" + lastStepName + "] returned an overrideLastStepName [" + runBackendStepOutput.getOverrideLastStepName() + "]!");
|
|
||||||
lastStepName = runBackendStepOutput.getOverrideLastStepName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// similarly, if the step produced an updatedFrontendStepList, propagate that data outward //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
if(runBackendStepOutput.getUpdatedFrontendStepList() != null)
|
|
||||||
{
|
|
||||||
LOG.debug("Process step [" + lastStepName + "] generated an updatedFrontendStepList [" + runBackendStepOutput.getUpdatedFrontendStepList().stream().map(s -> s.getName()).toList() + "]!");
|
|
||||||
runProcessOutput.setUpdatedFrontendStepList(runBackendStepOutput.getUpdatedFrontendStepList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////
|
|
||||||
// in case we have a different step type, throw //
|
|
||||||
//////////////////////////////////////////////////
|
|
||||||
throw (new QException("Unsure how to run a step of type: " + step.getClass().getName()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -259,6 +182,270 @@ public class RunProcessAction
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void runLinearStepLoop(QProcessMetaData process, ProcessState processState, UUIDAndTypeStateKey stateKey, RunProcessInput runProcessInput, RunProcessOutput runProcessOutput) throws Exception
|
||||||
|
{
|
||||||
|
String lastStepName = runProcessInput.getStartAfterStep();
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// always refresh the step list - as any step that runs can modify it (in the process state). //
|
||||||
|
// this is why we don't do a loop over the step list - as we'd get ConcurrentModificationExceptions. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
List<QStepMetaData> stepList = getAvailableStepList(processState, process, lastStepName);
|
||||||
|
if(stepList.isEmpty())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStepMetaData step = stepList.get(0);
|
||||||
|
lastStepName = step.getName();
|
||||||
|
|
||||||
|
if(step instanceof QFrontendStepMetaData frontendStep)
|
||||||
|
{
|
||||||
|
LoopTodo loopTodo = prepareForFrontendStep(runProcessInput, process, frontendStep, processState);
|
||||||
|
if(loopTodo == LoopTodo.BREAK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(step instanceof QBackendStepMetaData backendStepMetaData)
|
||||||
|
{
|
||||||
|
RunBackendStepOutput runBackendStepOutput = runBackendStep(process, processState, stateKey, runProcessInput, runProcessOutput, backendStepMetaData, step);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the step returned an override lastStepName, use that to determine how we proceed //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(runBackendStepOutput.getOverrideLastStepName() != null)
|
||||||
|
{
|
||||||
|
LOG.debug("Process step [" + lastStepName + "] returned an overrideLastStepName [" + runBackendStepOutput.getOverrideLastStepName() + "]!");
|
||||||
|
lastStepName = runBackendStepOutput.getOverrideLastStepName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// in case we have a different step type, throw //
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
throw (new QException("Unsure how to run a step of type: " + step.getClass().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private enum LoopTodo
|
||||||
|
{
|
||||||
|
BREAK,
|
||||||
|
CONTINUE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private LoopTodo prepareForFrontendStep(RunProcessInput runProcessInput, QProcessMetaData process, QFrontendStepMetaData step, ProcessState processState) throws QException
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// Handle what to do with frontend steps, per request setting //
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
switch(runProcessInput.getFrontendStepBehavior())
|
||||||
|
{
|
||||||
|
case BREAK ->
|
||||||
|
{
|
||||||
|
LOG.trace("Breaking process [" + process.getName() + "] at frontend step (as requested by caller): " + step.getName());
|
||||||
|
processFrontendStepFieldDefaultValues(processState, step);
|
||||||
|
processFrontendComponents(processState, step);
|
||||||
|
processState.setNextStepName(step.getName());
|
||||||
|
return LoopTodo.BREAK;
|
||||||
|
}
|
||||||
|
case SKIP ->
|
||||||
|
{
|
||||||
|
LOG.trace("Skipping frontend step [" + step.getName() + "] in process [" + process.getName() + "] (as requested by caller)");
|
||||||
|
return LoopTodo.CONTINUE;
|
||||||
|
}
|
||||||
|
case FAIL ->
|
||||||
|
{
|
||||||
|
LOG.trace("Throwing error for frontend step [" + step.getName() + "] in process [" + process.getName() + "] (as requested by caller)");
|
||||||
|
throw (new QException("Failing process at step " + step.getName() + " (as requested, to fail on frontend steps)"));
|
||||||
|
}
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + runProcessInput.getFrontendStepBehavior());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void runStateMachineStep(String lastStepName, QProcessMetaData process, ProcessState processState, UUIDAndTypeStateKey stateKey, RunProcessInput runProcessInput, RunProcessOutput runProcessOutput, int stackDepth) throws Exception
|
||||||
|
{
|
||||||
|
//////////////////////////////
|
||||||
|
// check for stack-overflow //
|
||||||
|
//////////////////////////////
|
||||||
|
Integer maxStateMachineProcessStepFlowStackDepth = Objects.requireNonNullElse(runProcessInput.getValueInteger("maxStateMachineProcessStepFlowStackDepth"), 20);
|
||||||
|
if(stackDepth > maxStateMachineProcessStepFlowStackDepth)
|
||||||
|
{
|
||||||
|
throw (new QException("StateMachine process recurred too many times (exceeded maxStateMachineProcessStepFlowStackDepth of " + maxStateMachineProcessStepFlowStackDepth + ")"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// figure out what step to run: //
|
||||||
|
//////////////////////////////////
|
||||||
|
QStepMetaData step = null;
|
||||||
|
if(!StringUtils.hasContent(lastStepName))
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// if no lastStepName is given, start at the process's first step //
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
if(CollectionUtils.nullSafeIsEmpty(process.getStepList()))
|
||||||
|
{
|
||||||
|
throw (new QException("Process [" + process.getName() + "] does not have a step list defined."));
|
||||||
|
}
|
||||||
|
step = process.getStepList().get(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/////////////////////////////////////
|
||||||
|
// else run the given lastStepName //
|
||||||
|
/////////////////////////////////////
|
||||||
|
processState.clearNextStepName();
|
||||||
|
step = process.getStep(lastStepName);
|
||||||
|
if(step == null)
|
||||||
|
{
|
||||||
|
throw (new QException("Could not find step by name [" + lastStepName + "]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// for the flow of: //
|
||||||
|
// we were on a frontend step (as a sub-step of a state machine step), //
|
||||||
|
// and now we're here to run that state-step's backend step - //
|
||||||
|
// find the state-machine step containing this frontend step. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
String skipSubStepsUntil = null;
|
||||||
|
if(step instanceof QFrontendStepMetaData frontendStepMetaData)
|
||||||
|
{
|
||||||
|
QStateMachineStep stateMachineStep = getStateMachineStepContainingSubStep(process, frontendStepMetaData.getName());
|
||||||
|
if(stateMachineStep == null)
|
||||||
|
{
|
||||||
|
throw (new QException("Could not find stateMachineStep that contains last-frontend step: " + frontendStepMetaData.getName()));
|
||||||
|
}
|
||||||
|
step = stateMachineStep;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// set this flag, to know to skip this frontend step in the sub-step loop below //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
skipSubStepsUntil = frontendStepMetaData.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(step instanceof QStateMachineStep stateMachineStep))
|
||||||
|
{
|
||||||
|
throw (new QException("Have a non-stateMachineStep in a process using stateMachine flow... " + step.getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// run the sub-steps //
|
||||||
|
///////////////////////
|
||||||
|
boolean ranAnySubSteps = false;
|
||||||
|
for(QStepMetaData subStep : stateMachineStep.getSubSteps())
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ok, well, skip them if this flag is set (and clear the flag once we've hit this sub-step) //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(skipSubStepsUntil != null)
|
||||||
|
{
|
||||||
|
if(skipSubStepsUntil.equals(subStep.getName()))
|
||||||
|
{
|
||||||
|
skipSubStepsUntil = null;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ranAnySubSteps = true;
|
||||||
|
if(subStep instanceof QFrontendStepMetaData frontendStep)
|
||||||
|
{
|
||||||
|
LoopTodo loopTodo = prepareForFrontendStep(runProcessInput, process, frontendStep, processState);
|
||||||
|
if(loopTodo == LoopTodo.BREAK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(subStep instanceof QBackendStepMetaData backendStepMetaData)
|
||||||
|
{
|
||||||
|
RunBackendStepOutput runBackendStepOutput = runBackendStep(process, processState, stateKey, runProcessInput, runProcessOutput, backendStepMetaData, step);
|
||||||
|
Optional<String> nextStepName = runBackendStepOutput.getProcessState().getNextStepName();
|
||||||
|
|
||||||
|
if(nextStepName.isEmpty() && StringUtils.hasContent(stateMachineStep.getDefaultNextStepName()))
|
||||||
|
{
|
||||||
|
nextStepName = Optional.of(stateMachineStep.getDefaultNextStepName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nextStepName.isPresent())
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if we've been given a next-step-name, go to that step now. //
|
||||||
|
// it might be a backend-only stateMachineStep, in which case, we should run that backend step now. //
|
||||||
|
// or it might be a frontend-then-backend step, in which case, we want to go to that frontend step. //
|
||||||
|
// if we weren't given a next-step-name, then we should stay in the same state - either to finish //
|
||||||
|
// its sub-steps, or, to fall out of the loop and end the process. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
processState.clearNextStepName();
|
||||||
|
runStateMachineStep(nextStepName.get(), process, processState, stateKey, runProcessInput, runProcessOutput, stackDepth + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// in case we have a different step type, throw //
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
throw (new QException("Unsure how to run a step of type: " + step.getClass().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ranAnySubSteps)
|
||||||
|
{
|
||||||
|
if(StringUtils.hasContent(stateMachineStep.getDefaultNextStepName()))
|
||||||
|
{
|
||||||
|
runStateMachineStep(stateMachineStep.getDefaultNextStepName(), process, processState, stateKey, runProcessInput, runProcessOutput, stackDepth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QStateMachineStep getStateMachineStepContainingSubStep(QProcessMetaData process, String stepName)
|
||||||
|
{
|
||||||
|
for(QStepMetaData step : process.getAllSteps().values())
|
||||||
|
{
|
||||||
|
if(step instanceof QStateMachineStep stateMachineStep)
|
||||||
|
{
|
||||||
|
for(QStepMetaData subStep : stateMachineStep.getSubSteps())
|
||||||
|
{
|
||||||
|
if(subStep.getName().equals(stepName))
|
||||||
|
{
|
||||||
|
return (stateMachineStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -336,12 +523,12 @@ public class RunProcessAction
|
|||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
runProcessInput.seedFromProcessState(optionalProcessState.get());
|
runProcessInput.seedFromProcessState(optionalProcessState.get());
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// if we're restoring an old state, we can discard a previously stored updatedFrontendStepList - //
|
// if we're restoring an old state, we can discard a previously stored processMetaDataAdjustment - //
|
||||||
// it is only needed on the transitional edge from a backend-step to a frontend step, but not //
|
// it is only needed on the transitional edge from a backend-step to a frontend step, but not //
|
||||||
// in the other directly //
|
// in the other directly //
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
optionalProcessState.get().setUpdatedFrontendStepList(null);
|
optionalProcessState.get().setProcessMetaDataAdjustment(null);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// if there were values from the caller, put those (back) in the request //
|
// if there were values from the caller, put those (back) in the request //
|
||||||
@ -356,16 +543,40 @@ public class RunProcessAction
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProcessState processState = optionalProcessState.get();
|
ProcessState processState = optionalProcessState.get();
|
||||||
processState.clearNextStepName();
|
|
||||||
return processState;
|
return processState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private RunBackendStepOutput runBackendStep(QProcessMetaData process, ProcessState processState, UUIDAndTypeStateKey stateKey, RunProcessInput runProcessInput, RunProcessOutput runProcessOutput, QBackendStepMetaData backendStepMetaData, QStepMetaData step) throws Exception
|
||||||
|
{
|
||||||
|
///////////////////////
|
||||||
|
// Run backend steps //
|
||||||
|
///////////////////////
|
||||||
|
LOG.debug("Running backend step [" + step.getName() + "] in process [" + process.getName() + "]");
|
||||||
|
RunBackendStepOutput runBackendStepOutput = runBackendStep(runProcessInput, process, runProcessOutput, stateKey, backendStepMetaData, process, processState);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// similarly, if the step produced a processMetaDataAdjustment, propagate that data outward //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(runBackendStepOutput.getProcessMetaDataAdjustment() != null)
|
||||||
|
{
|
||||||
|
LOG.debug("Process step [" + step.getName() + "] generated a ProcessMetaDataAdjustment [" + runBackendStepOutput.getProcessMetaDataAdjustment() + "]!");
|
||||||
|
runProcessOutput.setProcessMetaDataAdjustment(runBackendStepOutput.getProcessMetaDataAdjustment());
|
||||||
|
}
|
||||||
|
|
||||||
|
return runBackendStepOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Run a single backend step.
|
** Run a single backend step.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected RunBackendStepOutput runBackendStep(RunProcessInput runProcessInput, QProcessMetaData process, RunProcessOutput runProcessOutput, UUIDAndTypeStateKey stateKey, QBackendStepMetaData backendStep, QProcessMetaData qProcessMetaData, ProcessState processState) throws Exception
|
RunBackendStepOutput runBackendStep(RunProcessInput runProcessInput, QProcessMetaData process, RunProcessOutput runProcessOutput, UUIDAndTypeStateKey stateKey, QBackendStepMetaData backendStep, QProcessMetaData qProcessMetaData, ProcessState processState) throws Exception
|
||||||
{
|
{
|
||||||
RunBackendStepInput runBackendStepInput = new RunBackendStepInput(processState);
|
RunBackendStepInput runBackendStepInput = new RunBackendStepInput(processState);
|
||||||
runBackendStepInput.setProcessName(process.getName());
|
runBackendStepInput.setProcessName(process.getName());
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.instances;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerHelper;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Version of AbstractQQQApplication that assumes all meta-data is produced
|
||||||
|
** by MetaDataProducers in a single package.
|
||||||
|
*******************************************************************************/
|
||||||
|
public abstract class AbstractMetaDataProducerBasedQQQApplication extends AbstractQQQApplication
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public abstract String getMetaDataPackageName();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QInstance defineQInstance() throws QException
|
||||||
|
{
|
||||||
|
QInstance qInstance = new QInstance();
|
||||||
|
MetaDataProducerHelper.processAllMetaDataProducersInPackage(qInstance, getMetaDataPackageName());
|
||||||
|
return (qInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.instances;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Base class to provide the definition of a QQQ-based application.
|
||||||
|
**
|
||||||
|
** Essentially, just how to define its meta-data - in the form of a QInstance.
|
||||||
|
**
|
||||||
|
** Also provides means to define the instance validation plugins to be used.
|
||||||
|
*******************************************************************************/
|
||||||
|
public abstract class AbstractQQQApplication
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public abstract QInstance defineQInstance() throws QException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public QInstance defineValidatedQInstance() throws QException, QInstanceValidationException
|
||||||
|
{
|
||||||
|
QInstance qInstance = defineQInstance();
|
||||||
|
|
||||||
|
QInstanceValidator.removeAllValidatorPlugins();
|
||||||
|
for(QInstanceValidatorPluginInterface<?> validatorPlugin : CollectionUtils.nonNullList(getValidatorPlugins()))
|
||||||
|
{
|
||||||
|
QInstanceValidator.addValidatorPlugin(validatorPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
QInstanceValidator qInstanceValidator = new QInstanceValidator();
|
||||||
|
qInstanceValidator.validate(qInstance);
|
||||||
|
return (qInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
protected List<QInstanceValidatorPluginInterface<?>> getValidatorPlugins()
|
||||||
|
{
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
@ -58,6 +58,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QComponentType;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStateMachineStep;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QSupplementalProcessMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QSupplementalProcessMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportDataSource;
|
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportDataSource;
|
||||||
@ -410,10 +411,27 @@ public class QInstanceEnricher
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private void enrichStep(QStepMetaData step)
|
private void enrichStep(QStepMetaData step)
|
||||||
|
{
|
||||||
|
enrichStep(step, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void enrichStep(QStepMetaData step, boolean isSubStep)
|
||||||
{
|
{
|
||||||
if(!StringUtils.hasContent(step.getLabel()))
|
if(!StringUtils.hasContent(step.getLabel()))
|
||||||
{
|
{
|
||||||
step.setLabel(nameToLabel(step.getName()));
|
if(isSubStep && (step.getName().endsWith(".backend") || step.getName().endsWith(".frontend")))
|
||||||
|
{
|
||||||
|
step.setLabel(nameToLabel(step.getName().replaceFirst("\\.(backend|frontend)", "")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
step.setLabel(nameToLabel(step.getName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
step.getInputFields().forEach(this::enrichField);
|
step.getInputFields().forEach(this::enrichField);
|
||||||
@ -434,6 +452,13 @@ public class QInstanceEnricher
|
|||||||
frontendStepMetaData.getRecordListFields().forEach(this::enrichField);
|
frontendStepMetaData.getRecordListFields().forEach(this::enrichField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(step instanceof QStateMachineStep stateMachineStep)
|
||||||
|
{
|
||||||
|
for(QStepMetaData subStep : CollectionUtils.nonNullList(stateMachineStep.getSubSteps()))
|
||||||
|
{
|
||||||
|
enrichStep(subStep, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ import com.kingsrook.qqq.backend.core.actions.automation.RecordAutomationHandler
|
|||||||
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
|
import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
|
||||||
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.AbstractWidgetRenderer;
|
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.AbstractWidgetRenderer;
|
||||||
import com.kingsrook.qqq.backend.core.actions.metadata.JoinGraph;
|
import com.kingsrook.qqq.backend.core.actions.metadata.JoinGraph;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.metadata.MetaDataFilterInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportCustomRecordSourceInterface;
|
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportCustomRecordSourceInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.scripts.TestScriptActionInterface;
|
import com.kingsrook.qqq.backend.core.actions.scripts.TestScriptActionInterface;
|
||||||
@ -74,6 +75,7 @@ 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.QAppMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppSection;
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppSection;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSourceType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
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.processes.QStepMetaData;
|
||||||
@ -185,6 +187,7 @@ public class QInstanceValidator
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
validateInstanceAttributes(qInstance);
|
||||||
validateBackends(qInstance);
|
validateBackends(qInstance);
|
||||||
validateAuthentication(qInstance);
|
validateAuthentication(qInstance);
|
||||||
validateAutomationProviders(qInstance);
|
validateAutomationProviders(qInstance);
|
||||||
@ -225,6 +228,19 @@ public class QInstanceValidator
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void validateInstanceAttributes(QInstance qInstance)
|
||||||
|
{
|
||||||
|
if(qInstance.getMetaDataFilter() != null)
|
||||||
|
{
|
||||||
|
validateSimpleCodeReference("Instance metaDataFilter ", qInstance.getMetaDataFilter(), MetaDataFilterInterface.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -928,13 +944,8 @@ public class QInstanceValidator
|
|||||||
assertCondition(Objects.equals(fieldName, field.getName()),
|
assertCondition(Objects.equals(fieldName, field.getName()),
|
||||||
"Inconsistent naming in table " + tableName + " for field " + fieldName + "/" + field.getName() + ".");
|
"Inconsistent naming in table " + tableName + " for field " + fieldName + "/" + field.getName() + ".");
|
||||||
|
|
||||||
if(field.getPossibleValueSourceName() != null)
|
|
||||||
{
|
|
||||||
assertCondition(qInstance.getPossibleValueSource(field.getPossibleValueSourceName()) != null,
|
|
||||||
"Unrecognized possibleValueSourceName " + field.getPossibleValueSourceName() + " in table " + tableName + " for field " + fieldName + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
String prefix = "Field " + fieldName + " in table " + tableName + " ";
|
String prefix = "Field " + fieldName + " in table " + tableName + " ";
|
||||||
|
validateFieldPossibleValueSourceAttributes(qInstance, field, prefix);
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
// validate things we know about field behaviors //
|
// validate things we know about field behaviors //
|
||||||
@ -1039,6 +1050,31 @@ public class QInstanceValidator
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void validateFieldPossibleValueSourceAttributes(QInstance qInstance, QFieldMetaData field, String prefix)
|
||||||
|
{
|
||||||
|
if(field.getPossibleValueSourceName() != null)
|
||||||
|
{
|
||||||
|
assertCondition(qInstance.getPossibleValueSource(field.getPossibleValueSourceName()) != null,
|
||||||
|
prefix + "has an unrecognized possibleValueSourceName " + field.getPossibleValueSourceName());
|
||||||
|
|
||||||
|
assertCondition(field.getInlinePossibleValueSource() == null, prefix.trim() + " has both a possibleValueSourceName and an inlinePossibleValueSource, which is not allowed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(field.getInlinePossibleValueSource() != null)
|
||||||
|
{
|
||||||
|
String name = "inlinePossibleValueSource for " + prefix.trim();
|
||||||
|
if(assertCondition(QPossibleValueSourceType.ENUM.equals(field.getInlinePossibleValueSource().getType()), name + " must have a type of ENUM."))
|
||||||
|
{
|
||||||
|
validatePossibleValueSource(qInstance, name, field.getInlinePossibleValueSource());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -1546,6 +1582,16 @@ public class QInstanceValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(QFieldMetaData field : process.getInputFields())
|
||||||
|
{
|
||||||
|
validateFieldPossibleValueSourceAttributes(qInstance, field, "Process " + processName + ", input field " + field.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(QFieldMetaData field : process.getOutputFields())
|
||||||
|
{
|
||||||
|
validateFieldPossibleValueSourceAttributes(qInstance, field, "Process " + processName + ", output field " + field.getName());
|
||||||
|
}
|
||||||
|
|
||||||
if(process.getCancelStep() != null)
|
if(process.getCancelStep() != null)
|
||||||
{
|
{
|
||||||
if(assertCondition(process.getCancelStep().getCode() != null, "Cancel step is missing a code reference, in process " + processName))
|
if(assertCondition(process.getCancelStep().getCode() != null, "Cancel step is missing a code reference, in process " + processName))
|
||||||
@ -1948,78 +1994,88 @@ public class QInstanceValidator
|
|||||||
qInstance.getPossibleValueSources().forEach((pvsName, possibleValueSource) ->
|
qInstance.getPossibleValueSources().forEach((pvsName, possibleValueSource) ->
|
||||||
{
|
{
|
||||||
assertCondition(Objects.equals(pvsName, possibleValueSource.getName()), "Inconsistent naming for possibleValueSource: " + pvsName + "/" + possibleValueSource.getName() + ".");
|
assertCondition(Objects.equals(pvsName, possibleValueSource.getName()), "Inconsistent naming for possibleValueSource: " + pvsName + "/" + possibleValueSource.getName() + ".");
|
||||||
if(assertCondition(possibleValueSource.getType() != null, "Missing type for possibleValueSource: " + pvsName))
|
validatePossibleValueSource(qInstance, pvsName, possibleValueSource);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void validatePossibleValueSource(QInstance qInstance, String name, QPossibleValueSource possibleValueSource)
|
||||||
|
{
|
||||||
|
if(assertCondition(possibleValueSource.getType() != null, "Missing type for possibleValueSource: " + name))
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// assert about fields that should and should not be set, based on possible value source type //
|
||||||
|
// do additional type-specific validations as well //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
switch(possibleValueSource.getType())
|
||||||
|
{
|
||||||
|
case ENUM ->
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
assertCondition(!StringUtils.hasContent(possibleValueSource.getTableName()), "enum-type possibleValueSource " + name + " should not have a tableName.");
|
||||||
// assert about fields that should and should not be set, based on possible value source type //
|
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "enum-type possibleValueSource " + name + " should not have searchFields.");
|
||||||
// do additional type-specific validations as well //
|
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "enum-type possibleValueSource " + name + " should not have orderByFields.");
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
assertCondition(possibleValueSource.getCustomCodeReference() == null, "enum-type possibleValueSource " + name + " should not have a customCodeReference.");
|
||||||
switch(possibleValueSource.getType())
|
|
||||||
|
assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getEnumValues()), "enum-type possibleValueSource " + name + " is missing enum values");
|
||||||
|
}
|
||||||
|
case TABLE ->
|
||||||
|
{
|
||||||
|
assertCondition(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getEnumValues()), "table-type possibleValueSource " + name + " should not have enum values.");
|
||||||
|
assertCondition(possibleValueSource.getCustomCodeReference() == null, "table-type possibleValueSource " + name + " should not have a customCodeReference.");
|
||||||
|
|
||||||
|
QTableMetaData tableMetaData = null;
|
||||||
|
if(assertCondition(StringUtils.hasContent(possibleValueSource.getTableName()), "table-type possibleValueSource " + name + " is missing a tableName."))
|
||||||
{
|
{
|
||||||
case ENUM ->
|
tableMetaData = qInstance.getTable(possibleValueSource.getTableName());
|
||||||
{
|
assertCondition(tableMetaData != null, "Unrecognized table " + possibleValueSource.getTableName() + " for possibleValueSource " + name + ".");
|
||||||
assertCondition(!StringUtils.hasContent(possibleValueSource.getTableName()), "enum-type possibleValueSource " + pvsName + " should not have a tableName.");
|
|
||||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "enum-type possibleValueSource " + pvsName + " should not have searchFields.");
|
|
||||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "enum-type possibleValueSource " + pvsName + " should not have orderByFields.");
|
|
||||||
assertCondition(possibleValueSource.getCustomCodeReference() == null, "enum-type possibleValueSource " + pvsName + " should not have a customCodeReference.");
|
|
||||||
|
|
||||||
assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getEnumValues()), "enum-type possibleValueSource " + pvsName + " is missing enum values");
|
|
||||||
}
|
|
||||||
case TABLE ->
|
|
||||||
{
|
|
||||||
assertCondition(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getEnumValues()), "table-type possibleValueSource " + pvsName + " should not have enum values.");
|
|
||||||
assertCondition(possibleValueSource.getCustomCodeReference() == null, "table-type possibleValueSource " + pvsName + " should not have a customCodeReference.");
|
|
||||||
|
|
||||||
QTableMetaData tableMetaData = null;
|
|
||||||
if(assertCondition(StringUtils.hasContent(possibleValueSource.getTableName()), "table-type possibleValueSource " + pvsName + " is missing a tableName."))
|
|
||||||
{
|
|
||||||
tableMetaData = qInstance.getTable(possibleValueSource.getTableName());
|
|
||||||
assertCondition(tableMetaData != null, "Unrecognized table " + possibleValueSource.getTableName() + " for possibleValueSource " + pvsName + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "table-type possibleValueSource " + pvsName + " is missing searchFields."))
|
|
||||||
{
|
|
||||||
if(tableMetaData != null)
|
|
||||||
{
|
|
||||||
QTableMetaData finalTableMetaData = tableMetaData;
|
|
||||||
for(String searchField : possibleValueSource.getSearchFields())
|
|
||||||
{
|
|
||||||
assertNoException(() -> finalTableMetaData.getField(searchField), "possibleValueSource " + pvsName + " has an unrecognized searchField: " + searchField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "table-type possibleValueSource " + pvsName + " is missing orderByFields."))
|
|
||||||
{
|
|
||||||
if(tableMetaData != null)
|
|
||||||
{
|
|
||||||
QTableMetaData finalTableMetaData = tableMetaData;
|
|
||||||
|
|
||||||
for(QFilterOrderBy orderByField : possibleValueSource.getOrderByFields())
|
|
||||||
{
|
|
||||||
assertNoException(() -> finalTableMetaData.getField(orderByField.getFieldName()), "possibleValueSource " + pvsName + " has an unrecognized orderByField: " + orderByField.getFieldName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case CUSTOM ->
|
|
||||||
{
|
|
||||||
assertCondition(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getEnumValues()), "custom-type possibleValueSource " + pvsName + " should not have enum values.");
|
|
||||||
assertCondition(!StringUtils.hasContent(possibleValueSource.getTableName()), "custom-type possibleValueSource " + pvsName + " should not have a tableName.");
|
|
||||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "custom-type possibleValueSource " + pvsName + " should not have searchFields.");
|
|
||||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "custom-type possibleValueSource " + pvsName + " should not have orderByFields.");
|
|
||||||
|
|
||||||
if(assertCondition(possibleValueSource.getCustomCodeReference() != null, "custom-type possibleValueSource " + pvsName + " is missing a customCodeReference."))
|
|
||||||
{
|
|
||||||
validateSimpleCodeReference("PossibleValueSource " + pvsName + " custom code reference: ", possibleValueSource.getCustomCodeReference(), QCustomPossibleValueProvider.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default -> errors.add("Unexpected possibleValueSource type: " + possibleValueSource.getType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runPlugins(QPossibleValueSource.class, possibleValueSource, qInstance);
|
if(assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "table-type possibleValueSource " + name + " is missing searchFields."))
|
||||||
|
{
|
||||||
|
if(tableMetaData != null)
|
||||||
|
{
|
||||||
|
QTableMetaData finalTableMetaData = tableMetaData;
|
||||||
|
for(String searchField : possibleValueSource.getSearchFields())
|
||||||
|
{
|
||||||
|
assertNoException(() -> finalTableMetaData.getField(searchField), "possibleValueSource " + name + " has an unrecognized searchField: " + searchField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(assertCondition(CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "table-type possibleValueSource " + name + " is missing orderByFields."))
|
||||||
|
{
|
||||||
|
if(tableMetaData != null)
|
||||||
|
{
|
||||||
|
QTableMetaData finalTableMetaData = tableMetaData;
|
||||||
|
|
||||||
|
for(QFilterOrderBy orderByField : possibleValueSource.getOrderByFields())
|
||||||
|
{
|
||||||
|
assertNoException(() -> finalTableMetaData.getField(orderByField.getFieldName()), "possibleValueSource " + name + " has an unrecognized orderByField: " + orderByField.getFieldName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
case CUSTOM ->
|
||||||
|
{
|
||||||
|
assertCondition(CollectionUtils.nullSafeIsEmpty(possibleValueSource.getEnumValues()), "custom-type possibleValueSource " + name + " should not have enum values.");
|
||||||
|
assertCondition(!StringUtils.hasContent(possibleValueSource.getTableName()), "custom-type possibleValueSource " + name + " should not have a tableName.");
|
||||||
|
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "custom-type possibleValueSource " + name + " should not have searchFields.");
|
||||||
|
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getOrderByFields()), "custom-type possibleValueSource " + name + " should not have orderByFields.");
|
||||||
|
|
||||||
|
if(assertCondition(possibleValueSource.getCustomCodeReference() != null, "custom-type possibleValueSource " + name + " is missing a customCodeReference."))
|
||||||
|
{
|
||||||
|
validateSimpleCodeReference("PossibleValueSource " + name + " custom code reference: ", possibleValueSource.getCustomCodeReference(), QCustomPossibleValueProvider.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> errors.add("Unexpected possibleValueSource type: " + possibleValueSource.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
runPlugins(QPossibleValueSource.class, possibleValueSource, qInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,16 @@ import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class MetaDataInput extends AbstractActionInput
|
public class MetaDataInput extends AbstractActionInput
|
||||||
{
|
{
|
||||||
|
private String frontendName;
|
||||||
|
private String frontendVersion;
|
||||||
|
|
||||||
|
private String middlewareName;
|
||||||
|
private String middlewareVersion;
|
||||||
|
|
||||||
|
private String applicationName;
|
||||||
|
private String applicationVersion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
@ -39,4 +49,190 @@ public class MetaDataInput extends AbstractActionInput
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for frontendName
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getFrontendName()
|
||||||
|
{
|
||||||
|
return (this.frontendName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for frontendName
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFrontendName(String frontendName)
|
||||||
|
{
|
||||||
|
this.frontendName = frontendName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for frontendName
|
||||||
|
*******************************************************************************/
|
||||||
|
public MetaDataInput withFrontendName(String frontendName)
|
||||||
|
{
|
||||||
|
this.frontendName = frontendName;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for frontendVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getFrontendVersion()
|
||||||
|
{
|
||||||
|
return (this.frontendVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for frontendVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFrontendVersion(String frontendVersion)
|
||||||
|
{
|
||||||
|
this.frontendVersion = frontendVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for frontendVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public MetaDataInput withFrontendVersion(String frontendVersion)
|
||||||
|
{
|
||||||
|
this.frontendVersion = frontendVersion;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for middlewareName
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getMiddlewareName()
|
||||||
|
{
|
||||||
|
return (this.middlewareName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for middlewareName
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setMiddlewareName(String middlewareName)
|
||||||
|
{
|
||||||
|
this.middlewareName = middlewareName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for middlewareName
|
||||||
|
*******************************************************************************/
|
||||||
|
public MetaDataInput withMiddlewareName(String middlewareName)
|
||||||
|
{
|
||||||
|
this.middlewareName = middlewareName;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for middlewareVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getMiddlewareVersion()
|
||||||
|
{
|
||||||
|
return (this.middlewareVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for middlewareVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setMiddlewareVersion(String middlewareVersion)
|
||||||
|
{
|
||||||
|
this.middlewareVersion = middlewareVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for middlewareVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public MetaDataInput withMiddlewareVersion(String middlewareVersion)
|
||||||
|
{
|
||||||
|
this.middlewareVersion = middlewareVersion;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for applicationName
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getApplicationName()
|
||||||
|
{
|
||||||
|
return (this.applicationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for applicationName
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setApplicationName(String applicationName)
|
||||||
|
{
|
||||||
|
this.applicationName = applicationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for applicationName
|
||||||
|
*******************************************************************************/
|
||||||
|
public MetaDataInput withApplicationName(String applicationName)
|
||||||
|
{
|
||||||
|
this.applicationName = applicationName;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for applicationVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getApplicationVersion()
|
||||||
|
{
|
||||||
|
return (this.applicationVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for applicationVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setApplicationVersion(String applicationVersion)
|
||||||
|
{
|
||||||
|
this.applicationVersion = applicationVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for applicationVersion
|
||||||
|
*******************************************************************************/
|
||||||
|
public MetaDataInput withApplicationVersion(String applicationVersion)
|
||||||
|
{
|
||||||
|
this.applicationVersion = applicationVersion;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.processes;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Object that stores adjustments that a process wants to make, at run-time,
|
||||||
|
** to its meta-data.
|
||||||
|
**
|
||||||
|
** e.g., changing the steps; updating fields (e.g., changing an inline PVS,
|
||||||
|
** or an isRequired attribute)
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ProcessMetaDataAdjustment
|
||||||
|
{
|
||||||
|
private static final QLogger LOG = QLogger.getLogger(ProcessMetaDataAdjustment.class);
|
||||||
|
|
||||||
|
private List<QFrontendStepMetaData> updatedFrontendStepList = null;
|
||||||
|
private Map<String, QFieldMetaData> updatedFields = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessMetaDataAdjustment withUpdatedField(QFieldMetaData field)
|
||||||
|
{
|
||||||
|
if(updatedFields == null)
|
||||||
|
{
|
||||||
|
updatedFields = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!StringUtils.hasContent(field.getName()))
|
||||||
|
{
|
||||||
|
LOG.warn("Missing name on field in withUpdatedField - no update will happen.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(updatedFields.containsKey(field.getName()))
|
||||||
|
{
|
||||||
|
LOG.info("UpdatedFields map already contained a field with this name - overwriting it.", logPair("fieldName", field.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedFields.put(field.getName(), field);
|
||||||
|
}
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for updatedFrontendStepList
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
||||||
|
{
|
||||||
|
return (this.updatedFrontendStepList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for updatedFrontendStepList
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
|
{
|
||||||
|
this.updatedFrontendStepList = updatedFrontendStepList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for updatedFrontendStepList
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessMetaDataAdjustment withUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
|
{
|
||||||
|
this.updatedFrontendStepList = updatedFrontendStepList;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for updatedFields
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, QFieldMetaData> getUpdatedFields()
|
||||||
|
{
|
||||||
|
return (this.updatedFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for updatedFields
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setUpdatedFields(Map<String, QFieldMetaData> updatedFields)
|
||||||
|
{
|
||||||
|
this.updatedFields = updatedFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for updatedFields
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessMetaDataAdjustment withUpdatedFields(Map<String, QFieldMetaData> updatedFields)
|
||||||
|
{
|
||||||
|
this.updatedFields = updatedFields;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -29,7 +29,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -42,10 +41,7 @@ public class ProcessState implements Serializable
|
|||||||
private List<String> stepList = new ArrayList<>();
|
private List<String> stepList = new ArrayList<>();
|
||||||
private Optional<String> nextStepName = Optional.empty();
|
private Optional<String> nextStepName = Optional.empty();
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
private ProcessMetaDataAdjustment processMetaDataAdjustment = null;
|
||||||
// maybe, remove this altogether - just let the frontend compute & send if needed... but how does it know last version...? //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
private List<QFrontendStepMetaData> updatedFrontendStepList = null;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -148,33 +144,36 @@ public class ProcessState implements Serializable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for updatedFrontendStepList
|
** Getter for processMetaDataAdjustment
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
public ProcessMetaDataAdjustment getProcessMetaDataAdjustment()
|
||||||
{
|
{
|
||||||
return (this.updatedFrontendStepList);
|
return (this.processMetaDataAdjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for updatedFrontendStepList
|
** Setter for processMetaDataAdjustment
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
public void setProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
||||||
{
|
{
|
||||||
this.updatedFrontendStepList = updatedFrontendStepList;
|
this.processMetaDataAdjustment = processMetaDataAdjustment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Fluent setter for updatedFrontendStepList
|
** Fluent setter for processMetaDataAdjustment
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public ProcessState withUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
public ProcessState withProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
||||||
{
|
{
|
||||||
this.updatedFrontendStepList = updatedFrontendStepList;
|
this.processMetaDataAdjustment = processMetaDataAdjustment;
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,13 @@ public class RunBackendStepOutput extends AbstractActionOutput implements Serial
|
|||||||
.map(step -> (QFrontendStepMetaData) step)
|
.map(step -> (QFrontendStepMetaData) step)
|
||||||
.toList());
|
.toList());
|
||||||
|
|
||||||
setUpdatedFrontendStepList(updatedFrontendStepList);
|
ProcessMetaDataAdjustment processMetaDataAdjustment = getProcessMetaDataAdjustment();
|
||||||
|
if(processMetaDataAdjustment == null)
|
||||||
|
{
|
||||||
|
processMetaDataAdjustment = new ProcessMetaDataAdjustment();
|
||||||
|
}
|
||||||
|
processMetaDataAdjustment.setUpdatedFrontendStepList(updatedFrontendStepList);
|
||||||
|
setProcessMetaDataAdjustment(processMetaDataAdjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -411,21 +417,21 @@ public class RunBackendStepOutput extends AbstractActionOutput implements Serial
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for updatedFrontendStepList
|
** Getter for ProcessMetaDataAdjustment (pass-through to processState)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
public ProcessMetaDataAdjustment getProcessMetaDataAdjustment()
|
||||||
{
|
{
|
||||||
return (this.processState.getUpdatedFrontendStepList());
|
return (this.processState.getProcessMetaDataAdjustment());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for updatedFrontendStepList
|
** Setter for updatedFrontendStepList (pass-through to processState)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
public void setProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
||||||
{
|
{
|
||||||
this.processState.setUpdatedFrontendStepList(updatedFrontendStepList);
|
this.processState.setProcessMetaDataAdjustment(processMetaDataAdjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import java.util.Optional;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ObjectUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -336,7 +337,12 @@ public class RunProcessOutput extends AbstractActionOutput implements Serializab
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
{
|
{
|
||||||
this.processState.setUpdatedFrontendStepList(updatedFrontendStepList);
|
if(this.processState.getProcessMetaDataAdjustment() == null)
|
||||||
|
{
|
||||||
|
this.processState.setProcessMetaDataAdjustment(new ProcessMetaDataAdjustment());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.processState.getProcessMetaDataAdjustment().setUpdatedFrontendStepList(updatedFrontendStepList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -346,7 +352,27 @@ public class RunProcessOutput extends AbstractActionOutput implements Serializab
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
||||||
{
|
{
|
||||||
return this.processState.getUpdatedFrontendStepList();
|
return ObjectUtils.tryElse(() -> this.processState.getProcessMetaDataAdjustment().getUpdatedFrontendStepList(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for processMetaDataAdjustment
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessMetaDataAdjustment getProcessMetaDataAdjustment()
|
||||||
|
{
|
||||||
|
return (this.processState.getProcessMetaDataAdjustment());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for processMetaDataAdjustment
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
||||||
|
{
|
||||||
|
this.processState.setProcessMetaDataAdjustment(processMetaDataAdjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,20 @@ public class CompositeWidgetData extends AbstractBlockWidgetData<CompositeWidget
|
|||||||
{
|
{
|
||||||
private List<AbstractBlockWidgetData<?, ?, ?, ?>> blocks = new ArrayList<>();
|
private List<AbstractBlockWidgetData<?, ?, ?, ?>> blocks = new ArrayList<>();
|
||||||
|
|
||||||
|
private ModalMode modalMode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum ModalMode
|
||||||
|
{
|
||||||
|
MODAL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Layout layout;
|
private Layout layout;
|
||||||
private Map<String, Serializable> styleOverrides = new HashMap<>();
|
private Map<String, Serializable> styleOverrides = new HashMap<>();
|
||||||
private String overlayHtml;
|
private String overlayHtml;
|
||||||
@ -52,12 +66,14 @@ public class CompositeWidgetData extends AbstractBlockWidgetData<CompositeWidget
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public enum Layout
|
public enum Layout
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// note, these are used in QQQ FMD CompositeWidgetData.tsx //
|
// note, these are used in QQQ FMD CompositeWidget.tsx //
|
||||||
/////////////////////////////////////////////////////////////
|
// and qqq-android CompositeWidgetBlock.kt //
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
FLEX_COLUMN,
|
FLEX_COLUMN,
|
||||||
FLEX_ROW_WRAPPED,
|
FLEX_ROW_WRAPPED,
|
||||||
FLEX_ROW_SPACE_BETWEEN,
|
FLEX_ROW_SPACE_BETWEEN,
|
||||||
|
FLEX_ROW_CENTER,
|
||||||
TABLE_SUB_ROW_DETAILS,
|
TABLE_SUB_ROW_DETAILS,
|
||||||
BADGES_WRAPPER
|
BADGES_WRAPPER
|
||||||
}
|
}
|
||||||
@ -306,4 +322,35 @@ public class CompositeWidgetData extends AbstractBlockWidgetData<CompositeWidget
|
|||||||
this.overlayStyleOverrides.put(key, value);
|
this.overlayStyleOverrides.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for modalMode
|
||||||
|
*******************************************************************************/
|
||||||
|
public ModalMode getModalMode()
|
||||||
|
{
|
||||||
|
return (this.modalMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for modalMode
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setModalMode(ModalMode modalMode)
|
||||||
|
{
|
||||||
|
this.modalMode = modalMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for modalMode
|
||||||
|
*******************************************************************************/
|
||||||
|
public CompositeWidgetData withModalMode(ModalMode modalMode)
|
||||||
|
{
|
||||||
|
this.modalMode = modalMode;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,11 @@ public abstract class AbstractBlockWidgetData<
|
|||||||
private V values;
|
private V values;
|
||||||
private SX styles;
|
private SX styles;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// optional field name to act as a 'guard' for the block - e.g., only include it //
|
||||||
|
// if the value for this field is true //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
private String conditional;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -443,4 +448,35 @@ public abstract class AbstractBlockWidgetData<
|
|||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for conditional
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getConditional()
|
||||||
|
{
|
||||||
|
return (this.conditional);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for conditional
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setConditional(String conditional)
|
||||||
|
{
|
||||||
|
this.conditional = conditional;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for conditional
|
||||||
|
*******************************************************************************/
|
||||||
|
public AbstractBlockWidgetData withConditional(String conditional)
|
||||||
|
{
|
||||||
|
this.conditional = conditional;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.audio;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.AbstractBlockWidgetData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseSlots;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseStyles;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** block that plays an audio file
|
||||||
|
*******************************************************************************/
|
||||||
|
public class AudioBlockData extends AbstractBlockWidgetData<AudioBlockData, AudioValues, BaseSlots, BaseStyles>
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public String getBlockTypeName()
|
||||||
|
{
|
||||||
|
return "AUDIO";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.audio;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockValuesInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class AudioValues implements BlockValuesInterface
|
||||||
|
{
|
||||||
|
private String path;
|
||||||
|
private boolean showControls = false;
|
||||||
|
private boolean autoPlay = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for path
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return (this.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for path
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPath(String path)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for path
|
||||||
|
*******************************************************************************/
|
||||||
|
public AudioValues withPath(String path)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for showControls
|
||||||
|
*******************************************************************************/
|
||||||
|
public boolean getShowControls()
|
||||||
|
{
|
||||||
|
return (this.showControls);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for showControls
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setShowControls(boolean showControls)
|
||||||
|
{
|
||||||
|
this.showControls = showControls;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for showControls
|
||||||
|
*******************************************************************************/
|
||||||
|
public AudioValues withShowControls(boolean showControls)
|
||||||
|
{
|
||||||
|
this.showControls = showControls;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for autoPlay
|
||||||
|
*******************************************************************************/
|
||||||
|
public boolean getAutoPlay()
|
||||||
|
{
|
||||||
|
return (this.autoPlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for autoPlay
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setAutoPlay(boolean autoPlay)
|
||||||
|
{
|
||||||
|
this.autoPlay = autoPlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for autoPlay
|
||||||
|
*******************************************************************************/
|
||||||
|
public AudioValues withAutoPlay(boolean autoPlay)
|
||||||
|
{
|
||||||
|
this.autoPlay = autoPlay;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -30,4 +30,335 @@ import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockStyles
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class BaseStyles implements BlockStylesInterface
|
public class BaseStyles implements BlockStylesInterface
|
||||||
{
|
{
|
||||||
|
private Directional<String> padding;
|
||||||
|
|
||||||
|
private String backgroundColor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static class Directional<T>
|
||||||
|
{
|
||||||
|
private T top;
|
||||||
|
private T bottom;
|
||||||
|
private T left;
|
||||||
|
private T right;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional(T top, T right, T bottom, T left)
|
||||||
|
{
|
||||||
|
this.top = top;
|
||||||
|
this.right = right;
|
||||||
|
this.bottom = bottom;
|
||||||
|
this.left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> of(T top, T right, T bottom, T left)
|
||||||
|
{
|
||||||
|
return (new Directional<>(top, right, bottom, left));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> of(T value)
|
||||||
|
{
|
||||||
|
return (new Directional<>(value, value, value, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofTop(T top)
|
||||||
|
{
|
||||||
|
return (new Directional<>(top, null, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofRight(T right)
|
||||||
|
{
|
||||||
|
return (new Directional<>(null, right, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofBottom(T bottom)
|
||||||
|
{
|
||||||
|
return (new Directional<>(null, null, bottom, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofLeft(T left)
|
||||||
|
{
|
||||||
|
return (new Directional<>(null, null, null, left));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofX(T x)
|
||||||
|
{
|
||||||
|
return (new Directional<>(null, x, null, x));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofY(T y)
|
||||||
|
{
|
||||||
|
return (new Directional<>(y, null, y, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static <T> Directional<T> ofXY(T x, T y)
|
||||||
|
{
|
||||||
|
return (new Directional<>(y, x, y, x));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for top
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public T getTop()
|
||||||
|
{
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for top
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setTop(T top)
|
||||||
|
{
|
||||||
|
this.top = top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for top
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional<T> withTop(T top)
|
||||||
|
{
|
||||||
|
this.top = top;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for bottom
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public T getBottom()
|
||||||
|
{
|
||||||
|
return bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for bottom
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setBottom(T bottom)
|
||||||
|
{
|
||||||
|
this.bottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for bottom
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional<T> withBottom(T bottom)
|
||||||
|
{
|
||||||
|
this.bottom = bottom;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for left
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public T getLeft()
|
||||||
|
{
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for left
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setLeft(T left)
|
||||||
|
{
|
||||||
|
this.left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for left
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional<T> withLeft(T left)
|
||||||
|
{
|
||||||
|
this.left = left;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for right
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public T getRight()
|
||||||
|
{
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for right
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setRight(T right)
|
||||||
|
{
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for right
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional<T> withRight(T right)
|
||||||
|
{
|
||||||
|
this.right = right;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for padding
|
||||||
|
*******************************************************************************/
|
||||||
|
public Directional<String> getPadding()
|
||||||
|
{
|
||||||
|
return (this.padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for padding
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPadding(Directional<String> padding)
|
||||||
|
{
|
||||||
|
this.padding = padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for padding
|
||||||
|
*******************************************************************************/
|
||||||
|
public BaseStyles withPadding(Directional<String> padding)
|
||||||
|
{
|
||||||
|
this.padding = padding;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for backgroundColor
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getBackgroundColor()
|
||||||
|
{
|
||||||
|
return (this.backgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for backgroundColor
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setBackgroundColor(String backgroundColor)
|
||||||
|
{
|
||||||
|
this.backgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for backgroundColor
|
||||||
|
*******************************************************************************/
|
||||||
|
public BaseStyles withBackgroundColor(String backgroundColor)
|
||||||
|
{
|
||||||
|
this.backgroundColor = backgroundColor;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.button;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.AbstractBlockWidgetData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseSlots;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** a button (for a process - not sure yet what this could do in a standalone
|
||||||
|
** widget?) to submit the process screen to run a specific action (e.g., not just
|
||||||
|
** 'next'), or do other control-ish things
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ButtonBlockData extends AbstractBlockWidgetData<ButtonBlockData, ButtonValues, BaseSlots, ButtonStyles>
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public String getBlockTypeName()
|
||||||
|
{
|
||||||
|
return "BUTTON";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.button;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockStylesInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ButtonStyles implements BlockStylesInterface
|
||||||
|
{
|
||||||
|
private String color;
|
||||||
|
private String format;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum StandardColor
|
||||||
|
{
|
||||||
|
SUCCESS,
|
||||||
|
WARNING,
|
||||||
|
ERROR,
|
||||||
|
INFO,
|
||||||
|
MUTED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum StandardFormat
|
||||||
|
{
|
||||||
|
OUTLINED,
|
||||||
|
FILLED,
|
||||||
|
TEXT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getColor()
|
||||||
|
{
|
||||||
|
return (this.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setColor(String color)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonStyles withColor(String color)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getFormat()
|
||||||
|
{
|
||||||
|
return (this.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFormat(String format)
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonStyles withFormat(String format)
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFormat(StandardFormat format)
|
||||||
|
{
|
||||||
|
this.format = (format == null ? null : format.name().toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonStyles withFormat(StandardFormat format)
|
||||||
|
{
|
||||||
|
setFormat(format);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.button;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockValuesInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ButtonValues implements BlockValuesInterface
|
||||||
|
{
|
||||||
|
private String label;
|
||||||
|
private String actionCode;
|
||||||
|
private String controlCode;
|
||||||
|
|
||||||
|
private QIcon startIcon;
|
||||||
|
private QIcon endIcon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues(String label, String actionCode)
|
||||||
|
{
|
||||||
|
setLabel(label);
|
||||||
|
setActionCode(actionCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for label
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getLabel()
|
||||||
|
{
|
||||||
|
return (this.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for label
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setLabel(String label)
|
||||||
|
{
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for label
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues withLabel(String label)
|
||||||
|
{
|
||||||
|
this.label = label;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for actionCode
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getActionCode()
|
||||||
|
{
|
||||||
|
return (this.actionCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for actionCode
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setActionCode(String actionCode)
|
||||||
|
{
|
||||||
|
this.actionCode = actionCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for actionCode
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues withActionCode(String actionCode)
|
||||||
|
{
|
||||||
|
this.actionCode = actionCode;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for startIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getStartIcon()
|
||||||
|
{
|
||||||
|
return (this.startIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for startIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setStartIcon(QIcon startIcon)
|
||||||
|
{
|
||||||
|
this.startIcon = startIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for startIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues withStartIcon(QIcon startIcon)
|
||||||
|
{
|
||||||
|
this.startIcon = startIcon;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for endIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getEndIcon()
|
||||||
|
{
|
||||||
|
return (this.endIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for endIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setEndIcon(QIcon endIcon)
|
||||||
|
{
|
||||||
|
this.endIcon = endIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for endIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues withEndIcon(QIcon endIcon)
|
||||||
|
{
|
||||||
|
this.endIcon = endIcon;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for controlCode
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getControlCode()
|
||||||
|
{
|
||||||
|
return (this.controlCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for controlCode
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setControlCode(String controlCode)
|
||||||
|
{
|
||||||
|
this.controlCode = controlCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for controlCode
|
||||||
|
*******************************************************************************/
|
||||||
|
public ButtonValues withControlCode(String controlCode)
|
||||||
|
{
|
||||||
|
this.controlCode = controlCode;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.image;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.AbstractBlockWidgetData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseSlots;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** block to display an image
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ImageBlockData extends AbstractBlockWidgetData<ImageBlockData, ImageValues, BaseSlots, ImageStyles>
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public String getBlockTypeName()
|
||||||
|
{
|
||||||
|
return "IMAGE";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.image;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseStyles;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ImageStyles extends BaseStyles
|
||||||
|
{
|
||||||
|
private String width;
|
||||||
|
private String height;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for padding
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public ImageStyles withPadding(Directional<String> padding)
|
||||||
|
{
|
||||||
|
super.setPadding(padding);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for width
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getWidth()
|
||||||
|
{
|
||||||
|
return (this.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for width
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setWidth(String width)
|
||||||
|
{
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for width
|
||||||
|
*******************************************************************************/
|
||||||
|
public ImageStyles withWidth(String width)
|
||||||
|
{
|
||||||
|
this.width = width;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for height
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getHeight()
|
||||||
|
{
|
||||||
|
return (this.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for height
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setHeight(String height)
|
||||||
|
{
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for height
|
||||||
|
*******************************************************************************/
|
||||||
|
public ImageStyles withHeight(String height)
|
||||||
|
{
|
||||||
|
this.height = height;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.image;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockValuesInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class ImageValues implements BlockValuesInterface
|
||||||
|
{
|
||||||
|
private String path;
|
||||||
|
private String alt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for path
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return (this.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for path
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPath(String path)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for path
|
||||||
|
*******************************************************************************/
|
||||||
|
public ImageValues withPath(String path)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for alt
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getAlt()
|
||||||
|
{
|
||||||
|
return (this.alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for alt
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setAlt(String alt)
|
||||||
|
{
|
||||||
|
this.alt = alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for alt
|
||||||
|
*******************************************************************************/
|
||||||
|
public ImageValues withAlt(String alt)
|
||||||
|
{
|
||||||
|
this.alt = alt;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.inputfield;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.AbstractBlockWidgetData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseSlots;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.base.BaseStyles;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** block to display an input field - initially targeted at widgets-in-processes
|
||||||
|
*******************************************************************************/
|
||||||
|
public class InputFieldBlockData extends AbstractBlockWidgetData<InputFieldBlockData, InputFieldValues, BaseSlots, BaseStyles>
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public String getBlockTypeName()
|
||||||
|
{
|
||||||
|
return "INPUT_FIELD";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.blocks.inputfield;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockValuesInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class InputFieldValues implements BlockValuesInterface
|
||||||
|
{
|
||||||
|
private QFieldMetaData fieldMetaData;
|
||||||
|
|
||||||
|
private Boolean autoFocus;
|
||||||
|
private Boolean submitOnEnter;
|
||||||
|
private Boolean hideSoftKeyboard;
|
||||||
|
private String placeholder;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues(QFieldMetaData fieldMetaData)
|
||||||
|
{
|
||||||
|
setFieldMetaData(fieldMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for fieldMetaData
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFieldMetaData getFieldMetaData()
|
||||||
|
{
|
||||||
|
return (this.fieldMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for fieldMetaData
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFieldMetaData(QFieldMetaData fieldMetaData)
|
||||||
|
{
|
||||||
|
this.fieldMetaData = fieldMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for fieldMetaData
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues withFieldMetaData(QFieldMetaData fieldMetaData)
|
||||||
|
{
|
||||||
|
this.fieldMetaData = fieldMetaData;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for autoFocus
|
||||||
|
*******************************************************************************/
|
||||||
|
public Boolean getAutoFocus()
|
||||||
|
{
|
||||||
|
return (this.autoFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for autoFocus
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setAutoFocus(Boolean autoFocus)
|
||||||
|
{
|
||||||
|
this.autoFocus = autoFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for autoFocus
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues withAutoFocus(Boolean autoFocus)
|
||||||
|
{
|
||||||
|
this.autoFocus = autoFocus;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for submitOnEnter
|
||||||
|
*******************************************************************************/
|
||||||
|
public Boolean getSubmitOnEnter()
|
||||||
|
{
|
||||||
|
return (this.submitOnEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for submitOnEnter
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setSubmitOnEnter(Boolean submitOnEnter)
|
||||||
|
{
|
||||||
|
this.submitOnEnter = submitOnEnter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for submitOnEnter
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues withSubmitOnEnter(Boolean submitOnEnter)
|
||||||
|
{
|
||||||
|
this.submitOnEnter = submitOnEnter;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for placeholder
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getPlaceholder()
|
||||||
|
{
|
||||||
|
return (this.placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for placeholder
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setPlaceholder(String placeholder)
|
||||||
|
{
|
||||||
|
this.placeholder = placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for placeholder
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues withPlaceholder(String placeholder)
|
||||||
|
{
|
||||||
|
this.placeholder = placeholder;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for hideSoftKeyboard
|
||||||
|
*******************************************************************************/
|
||||||
|
public Boolean getHideSoftKeyboard()
|
||||||
|
{
|
||||||
|
return (this.hideSoftKeyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for hideSoftKeyboard
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setHideSoftKeyboard(Boolean hideSoftKeyboard)
|
||||||
|
{
|
||||||
|
this.hideSoftKeyboard = hideSoftKeyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for hideSoftKeyboard
|
||||||
|
*******************************************************************************/
|
||||||
|
public InputFieldValues withHideSoftKeyboard(Boolean hideSoftKeyboard)
|
||||||
|
{
|
||||||
|
this.hideSoftKeyboard = hideSoftKeyboard;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -30,4 +30,325 @@ import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockStyles
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class TextStyles implements BlockStylesInterface
|
public class TextStyles implements BlockStylesInterface
|
||||||
{
|
{
|
||||||
|
private String color;
|
||||||
|
private String format;
|
||||||
|
private String weight;
|
||||||
|
private String size;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum StandardColor
|
||||||
|
{
|
||||||
|
SUCCESS,
|
||||||
|
WARNING,
|
||||||
|
ERROR,
|
||||||
|
INFO,
|
||||||
|
MUTED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum StandardFormat
|
||||||
|
{
|
||||||
|
DEFAULT,
|
||||||
|
ALERT,
|
||||||
|
BANNER
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum StandardSize
|
||||||
|
{
|
||||||
|
LARGEST,
|
||||||
|
HEADLINE,
|
||||||
|
TITLE,
|
||||||
|
BODY,
|
||||||
|
SMALLEST
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public enum StandardWeight
|
||||||
|
{
|
||||||
|
EXTRA_LIGHT("extralight"),
|
||||||
|
THIN("thin"),
|
||||||
|
MEDIUM("medium"),
|
||||||
|
SEMI_BOLD("semibold"),
|
||||||
|
BLACK("black"),
|
||||||
|
BOLD("bold"),
|
||||||
|
EXTRA_BOLD("extrabold"),
|
||||||
|
W100("100"),
|
||||||
|
W200("200"),
|
||||||
|
W300("300"),
|
||||||
|
W400("400"),
|
||||||
|
W500("500"),
|
||||||
|
W600("600"),
|
||||||
|
W700("700"),
|
||||||
|
W800("800"),
|
||||||
|
W900("900");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
StandardWeight(String value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for value
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getValue()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public TextStyles(StandardColor standardColor)
|
||||||
|
{
|
||||||
|
setColor(standardColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getFormat()
|
||||||
|
{
|
||||||
|
return (this.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFormat(String format)
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withFormat(String format)
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFormat(StandardFormat format)
|
||||||
|
{
|
||||||
|
this.format = format == null ? null : format.name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withFormat(StandardFormat format)
|
||||||
|
{
|
||||||
|
this.setFormat(format);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for weight
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getWeight()
|
||||||
|
{
|
||||||
|
return (this.weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for weight
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setWeight(String weight)
|
||||||
|
{
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for weight
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withWeight(String weight)
|
||||||
|
{
|
||||||
|
this.weight = weight;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for weight
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setWeight(StandardWeight weight)
|
||||||
|
{
|
||||||
|
setWeight(weight == null ? null : weight.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for weight
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withWeight(StandardWeight weight)
|
||||||
|
{
|
||||||
|
setWeight(weight);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for size
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getSize()
|
||||||
|
{
|
||||||
|
return (this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for size
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setSize(String size)
|
||||||
|
{
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for size
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withSize(String size)
|
||||||
|
{
|
||||||
|
this.size = size;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for size
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setSize(StandardSize size)
|
||||||
|
{
|
||||||
|
this.size = (size == null ? null : size.name().toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for size
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withSize(StandardSize size)
|
||||||
|
{
|
||||||
|
setSize(size);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getColor()
|
||||||
|
{
|
||||||
|
return (this.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setColor(String color)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withColor(String color)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setColor(StandardColor color)
|
||||||
|
{
|
||||||
|
this.color = color == null ? null : color.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for color
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextStyles withColor(StandardColor color)
|
||||||
|
{
|
||||||
|
setColor(color);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.text;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockValuesInterface;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks.BlockValuesInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -32,6 +33,9 @@ public class TextValues implements BlockValuesInterface
|
|||||||
{
|
{
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
|
private QIcon startIcon;
|
||||||
|
private QIcon endIcon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -84,4 +88,66 @@ public class TextValues implements BlockValuesInterface
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for startIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getStartIcon()
|
||||||
|
{
|
||||||
|
return (this.startIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for startIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setStartIcon(QIcon startIcon)
|
||||||
|
{
|
||||||
|
this.startIcon = startIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for startIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextValues withStartIcon(QIcon startIcon)
|
||||||
|
{
|
||||||
|
this.startIcon = startIcon;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for endIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getEndIcon()
|
||||||
|
{
|
||||||
|
return (this.endIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for endIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setEndIcon(QIcon endIcon)
|
||||||
|
{
|
||||||
|
this.endIcon = endIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for endIcon
|
||||||
|
*******************************************************************************/
|
||||||
|
public TextValues withEndIcon(QIcon endIcon)
|
||||||
|
{
|
||||||
|
this.endIcon = endIcon;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,6 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Abstract class that knows how to produce meta data objects. Useful with
|
** Abstract class that knows how to produce meta data objects. Useful with
|
||||||
** MetaDataProducerHelper, to put point at a package full of these, and populate
|
** MetaDataProducerHelper, to put point at a package full of these, and populate
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -30,14 +29,12 @@ import java.util.Comparator;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.reflect.ClassPath;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ClassPathUtils;
|
||||||
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||||
|
|
||||||
|
|
||||||
@ -51,8 +48,6 @@ public class MetaDataProducerHelper
|
|||||||
private static Map<Class<?>, Integer> comparatorValuesByType = new HashMap<>();
|
private static Map<Class<?>, Integer> comparatorValuesByType = new HashMap<>();
|
||||||
private static Integer defaultComparatorValue;
|
private static Integer defaultComparatorValue;
|
||||||
|
|
||||||
private static ImmutableSet<ClassPath.ClassInfo> topLevelClasses;
|
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -87,7 +82,7 @@ public class MetaDataProducerHelper
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// find all the meta data producer classes in (and under) the package //
|
// find all the meta data producer classes in (and under) the package //
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
classesInPackage = getClassesInPackage(packageName);
|
classesInPackage = ClassPathUtils.getClassesInPackage(packageName);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -176,51 +171,4 @@ public class MetaDataProducerHelper
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** from https://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection
|
|
||||||
** (since the original, from ChatGPT, didn't work in jars, despite GPT hallucinating that it would)
|
|
||||||
*******************************************************************************/
|
|
||||||
private static List<Class<?>> getClassesInPackage(String packageName) throws IOException
|
|
||||||
{
|
|
||||||
List<Class<?>> classes = new ArrayList<>();
|
|
||||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
|
||||||
|
|
||||||
for(ClassPath.ClassInfo info : getTopLevelClasses(loader))
|
|
||||||
{
|
|
||||||
if(info.getName().startsWith(packageName))
|
|
||||||
{
|
|
||||||
classes.add(info.load());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
private static ImmutableSet<ClassPath.ClassInfo> getTopLevelClasses(ClassLoader loader) throws IOException
|
|
||||||
{
|
|
||||||
if(topLevelClasses == null)
|
|
||||||
{
|
|
||||||
topLevelClasses = ClassPath.from(loader).getTopLevelClasses();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (topLevelClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public static void clearTopLevelClassCache()
|
|
||||||
{
|
|
||||||
topLevelClasses = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* QQQ - Low-code Application Framework for Engineers.
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
* Copyright (C) 2021-2023. Kingsrook, LLC
|
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
* contact@kingsrook.com
|
* contact@kingsrook.com
|
||||||
* https://github.com/Kingsrook/
|
* https://github.com/Kingsrook/
|
||||||
@ -19,12 +19,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.kingsrook.qqq.backend.core.model;
|
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerOutput;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
@ -43,6 +43,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.audits.QAuditRules;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.branding.QBrandingMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.branding.QBrandingMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNodeType;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNodeType;
|
||||||
@ -113,6 +114,8 @@ public class QInstance
|
|||||||
private QPermissionRules defaultPermissionRules = QPermissionRules.defaultInstance();
|
private QPermissionRules defaultPermissionRules = QPermissionRules.defaultInstance();
|
||||||
private QAuditRules defaultAuditRules = QAuditRules.defaultInstanceLevelNone();
|
private QAuditRules defaultAuditRules = QAuditRules.defaultInstanceLevelNone();
|
||||||
|
|
||||||
|
private QCodeReference metaDataFilter = null;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
// todo - lock down the object (no more changes allowed) after it's been validated? //
|
// todo - lock down the object (no more changes allowed) after it's been validated? //
|
||||||
// if doing so, may need to copy all of the collections into read-only versions... //
|
// if doing so, may need to copy all of the collections into read-only versions... //
|
||||||
@ -1485,4 +1488,35 @@ public class QInstance
|
|||||||
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, listForSlot);
|
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, listForSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for metaDataFilter
|
||||||
|
*******************************************************************************/
|
||||||
|
public QCodeReference getMetaDataFilter()
|
||||||
|
{
|
||||||
|
return (this.metaDataFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for metaDataFilter
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setMetaDataFilter(QCodeReference metaDataFilter)
|
||||||
|
{
|
||||||
|
this.metaDataFilter = metaDataFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for metaDataFilter
|
||||||
|
*******************************************************************************/
|
||||||
|
public QInstance withMetaDataFilter(QCodeReference metaDataFilter)
|
||||||
|
{
|
||||||
|
this.metaDataFilter = metaDataFilter;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ public class QAuthenticationMetaData implements TopLevelMetaDataInterface
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QAuthenticationMetaData withVales(Map<String, String> values)
|
public QAuthenticationMetaData withValues(Map<String, String> values)
|
||||||
{
|
{
|
||||||
this.values = values;
|
this.values = values;
|
||||||
return (this);
|
return (this);
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.code;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Specialized type of QCodeReference that takes a lambda function object.
|
||||||
|
**
|
||||||
|
** Originally intended for more concise setup of backend steps in tests - but,
|
||||||
|
** may be generally useful.
|
||||||
|
*******************************************************************************/
|
||||||
|
public class QCodeReferenceLambda<T> extends QCodeReference
|
||||||
|
{
|
||||||
|
private final T lambda;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public QCodeReferenceLambda(T lambda)
|
||||||
|
{
|
||||||
|
this.lambda = lambda;
|
||||||
|
this.setCodeType(QCodeType.JAVA);
|
||||||
|
this.setName("[Lambda:" + lambda.toString() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for lambda
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public T getLambda()
|
||||||
|
{
|
||||||
|
return lambda;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -42,6 +42,7 @@ import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
|
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
|
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.security.FieldSecurityLock;
|
import com.kingsrook.qqq.backend.core.model.metadata.security.FieldSecurityLock;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
@ -73,10 +74,12 @@ public class QFieldMetaData implements Cloneable
|
|||||||
// propose doing that in a secondary field, e.g., "onlyEditableOn=insert|update" //
|
// propose doing that in a secondary field, e.g., "onlyEditableOn=insert|update" //
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private String displayFormat = "%s";
|
private String displayFormat = "%s";
|
||||||
private Serializable defaultValue;
|
private Serializable defaultValue;
|
||||||
private String possibleValueSourceName;
|
|
||||||
private QQueryFilter possibleValueSourceFilter;
|
private String possibleValueSourceName;
|
||||||
|
private QQueryFilter possibleValueSourceFilter;
|
||||||
|
private QPossibleValueSource inlinePossibleValueSource;
|
||||||
|
|
||||||
private Integer maxLength;
|
private Integer maxLength;
|
||||||
private Set<FieldBehavior<?>> behaviors;
|
private Set<FieldBehavior<?>> behaviors;
|
||||||
@ -1058,4 +1061,35 @@ public class QFieldMetaData implements Cloneable
|
|||||||
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, this.helpContents);
|
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, this.helpContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for inlinePossibleValueSource
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource getInlinePossibleValueSource()
|
||||||
|
{
|
||||||
|
return (this.inlinePossibleValueSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for inlinePossibleValueSource
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setInlinePossibleValueSource(QPossibleValueSource inlinePossibleValueSource)
|
||||||
|
{
|
||||||
|
this.inlinePossibleValueSource = inlinePossibleValueSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for inlinePossibleValueSource
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFieldMetaData withInlinePossibleValueSource(QPossibleValueSource inlinePossibleValueSource)
|
||||||
|
{
|
||||||
|
this.inlinePossibleValueSource = inlinePossibleValueSource;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppChildMetaData;
|
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.QAppMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
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.reporting.QReportMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
@ -45,7 +46,7 @@ public class AppTreeNode
|
|||||||
private String label;
|
private String label;
|
||||||
private List<AppTreeNode> children;
|
private List<AppTreeNode> children;
|
||||||
|
|
||||||
private String iconName;
|
private QIcon icon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ public class AppTreeNode
|
|||||||
if(appChildMetaData.getIcon() != null)
|
if(appChildMetaData.getIcon() != null)
|
||||||
{
|
{
|
||||||
// todo - propagate icons from parents, if they aren't set here...
|
// todo - propagate icons from parents, if they aren't set here...
|
||||||
this.iconName = appChildMetaData.getIcon().getName();
|
this.icon = appChildMetaData.getIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +139,18 @@ public class AppTreeNode
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return iconName;
|
return (icon == null ? null : icon.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for icon
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getIcon()
|
||||||
|
{
|
||||||
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
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.QAppSection;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QSupplementalAppMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QSupplementalAppMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ public class QFrontendAppMetaData
|
|||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
private String label;
|
private String label;
|
||||||
private String iconName;
|
private QIcon icon;
|
||||||
|
|
||||||
private List<String> widgets = new ArrayList<>();
|
private List<String> widgets = new ArrayList<>();
|
||||||
private List<AppTreeNode> children = new ArrayList<>();
|
private List<AppTreeNode> children = new ArrayList<>();
|
||||||
@ -56,6 +57,7 @@ public class QFrontendAppMetaData
|
|||||||
private Map<String, QSupplementalAppMetaData> supplementalAppMetaData;
|
private Map<String, QSupplementalAppMetaData> supplementalAppMetaData;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -63,11 +65,7 @@ public class QFrontendAppMetaData
|
|||||||
{
|
{
|
||||||
this.name = appMetaData.getName();
|
this.name = appMetaData.getName();
|
||||||
this.label = appMetaData.getLabel();
|
this.label = appMetaData.getLabel();
|
||||||
|
this.icon = appMetaData.getIcon();
|
||||||
if(appMetaData.getIcon() != null)
|
|
||||||
{
|
|
||||||
this.iconName = appMetaData.getIcon().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> filteredWidgets = CollectionUtils.nonNullList(appMetaData.getWidgets()).stream().filter(n -> metaDataOutput.getWidgets().containsKey(n)).toList();
|
List<String> filteredWidgets = CollectionUtils.nonNullList(appMetaData.getWidgets()).stream().filter(n -> metaDataOutput.getWidgets().containsKey(n)).toList();
|
||||||
if(CollectionUtils.nullSafeHasContents(filteredWidgets))
|
if(CollectionUtils.nullSafeHasContents(filteredWidgets))
|
||||||
@ -81,6 +79,10 @@ public class QFrontendAppMetaData
|
|||||||
List<String> filteredTables = CollectionUtils.nonNullList(section.getTables()).stream().filter(n -> metaDataOutput.getTables().containsKey(n)).toList();
|
List<String> filteredTables = CollectionUtils.nonNullList(section.getTables()).stream().filter(n -> metaDataOutput.getTables().containsKey(n)).toList();
|
||||||
List<String> filteredProcesses = CollectionUtils.nonNullList(section.getProcesses()).stream().filter(n -> metaDataOutput.getProcesses().containsKey(n)).toList();
|
List<String> filteredProcesses = CollectionUtils.nonNullList(section.getProcesses()).stream().filter(n -> metaDataOutput.getProcesses().containsKey(n)).toList();
|
||||||
List<String> filteredReports = CollectionUtils.nonNullList(section.getReports()).stream().filter(n -> metaDataOutput.getReports().containsKey(n)).toList();
|
List<String> filteredReports = CollectionUtils.nonNullList(section.getReports()).stream().filter(n -> metaDataOutput.getReports().containsKey(n)).toList();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// only include the section if it has some contents //
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
if(!filteredTables.isEmpty() || !filteredProcesses.isEmpty() || !filteredReports.isEmpty())
|
if(!filteredTables.isEmpty() || !filteredProcesses.isEmpty() || !filteredReports.isEmpty())
|
||||||
{
|
{
|
||||||
QAppSection clonedSection = section.clone();
|
QAppSection clonedSection = section.clone();
|
||||||
@ -174,18 +176,7 @@ public class QFrontendAppMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return iconName;
|
return (icon == null ? null : icon.getName());
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for iconName
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setIconName(String iconName)
|
|
||||||
{
|
|
||||||
this.iconName = iconName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -235,4 +226,15 @@ public class QFrontendAppMetaData
|
|||||||
{
|
{
|
||||||
return supplementalAppMetaData;
|
return supplementalAppMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for icon
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getIcon()
|
||||||
|
{
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldBehaviorForFron
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
|
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ public class QFrontendFieldMetaData
|
|||||||
|
|
||||||
private List<FieldAdornment> adornments;
|
private List<FieldAdornment> adornments;
|
||||||
private List<QHelpContent> helpContents;
|
private List<QHelpContent> helpContents;
|
||||||
|
private QPossibleValueSource inlinePossibleValueSource;
|
||||||
|
|
||||||
private List<FieldBehaviorForFrontend> behaviors;
|
private List<FieldBehaviorForFrontend> behaviors;
|
||||||
|
|
||||||
@ -81,6 +83,7 @@ public class QFrontendFieldMetaData
|
|||||||
this.adornments = fieldMetaData.getAdornments();
|
this.adornments = fieldMetaData.getAdornments();
|
||||||
this.defaultValue = fieldMetaData.getDefaultValue();
|
this.defaultValue = fieldMetaData.getDefaultValue();
|
||||||
this.helpContents = fieldMetaData.getHelpContents();
|
this.helpContents = fieldMetaData.getHelpContents();
|
||||||
|
this.inlinePossibleValueSource = fieldMetaData.getInlinePossibleValueSource();
|
||||||
|
|
||||||
for(FieldBehavior<?> behavior : CollectionUtils.nonNullCollection(fieldMetaData.getBehaviors()))
|
for(FieldBehavior<?> behavior : CollectionUtils.nonNullCollection(fieldMetaData.getBehaviors()))
|
||||||
{
|
{
|
||||||
@ -218,6 +221,17 @@ public class QFrontendFieldMetaData
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for inlinePossibleValueSource
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QPossibleValueSource getInlinePossibleValueSource()
|
||||||
|
{
|
||||||
|
return inlinePossibleValueSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for fieldBehaviors
|
** Getter for fieldBehaviors
|
||||||
**
|
**
|
||||||
|
@ -29,8 +29,10 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
|||||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStateMachineStep;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -47,9 +49,10 @@ public class QFrontendProcessMetaData
|
|||||||
private String tableName;
|
private String tableName;
|
||||||
private boolean isHidden;
|
private boolean isHidden;
|
||||||
|
|
||||||
private String iconName;
|
private QIcon icon;
|
||||||
|
|
||||||
private List<QFrontendStepMetaData> frontendSteps;
|
private List<QFrontendStepMetaData> frontendSteps;
|
||||||
|
private String stepFlow;
|
||||||
|
|
||||||
private boolean hasPermission;
|
private boolean hasPermission;
|
||||||
|
|
||||||
@ -68,15 +71,27 @@ public class QFrontendProcessMetaData
|
|||||||
this.label = processMetaData.getLabel();
|
this.label = processMetaData.getLabel();
|
||||||
this.tableName = processMetaData.getTableName();
|
this.tableName = processMetaData.getTableName();
|
||||||
this.isHidden = processMetaData.getIsHidden();
|
this.isHidden = processMetaData.getIsHidden();
|
||||||
|
this.stepFlow = processMetaData.getStepFlow().toString();
|
||||||
|
|
||||||
if(includeSteps)
|
if(includeSteps)
|
||||||
{
|
{
|
||||||
if(CollectionUtils.nullSafeHasContents(processMetaData.getStepList()))
|
if(CollectionUtils.nullSafeHasContents(processMetaData.getStepList()))
|
||||||
{
|
{
|
||||||
this.frontendSteps = processMetaData.getStepList().stream()
|
this.frontendSteps = switch(processMetaData.getStepFlow())
|
||||||
.filter(QFrontendStepMetaData.class::isInstance)
|
{
|
||||||
.map(QFrontendStepMetaData.class::cast)
|
case LINEAR -> processMetaData.getStepList().stream()
|
||||||
.collect(Collectors.toList());
|
.filter(QFrontendStepMetaData.class::isInstance)
|
||||||
|
.map(QFrontendStepMetaData.class::cast)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
case STATE_MACHINE -> processMetaData.getAllSteps().values().stream()
|
||||||
|
.filter(QStateMachineStep.class::isInstance)
|
||||||
|
.map(QStateMachineStep.class::cast)
|
||||||
|
.flatMap(step -> step.getSubSteps().stream())
|
||||||
|
.filter(QFrontendStepMetaData.class::isInstance)
|
||||||
|
.map(QFrontendStepMetaData.class::cast)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -84,10 +99,7 @@ public class QFrontendProcessMetaData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(processMetaData.getIcon() != null)
|
this.icon = processMetaData.getIcon();
|
||||||
{
|
|
||||||
this.iconName = processMetaData.getIcon().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPermission = PermissionsHelper.hasProcessPermission(actionInput, name);
|
hasPermission = PermissionsHelper.hasProcessPermission(actionInput, name);
|
||||||
}
|
}
|
||||||
@ -166,7 +178,7 @@ public class QFrontendProcessMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return iconName;
|
return icon == null ? null : icon.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,4 +192,25 @@ public class QFrontendProcessMetaData
|
|||||||
return hasPermission;
|
return hasPermission;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for stepFlow
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getStepFlow()
|
||||||
|
{
|
||||||
|
return stepFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for icon
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getIcon()
|
||||||
|
{
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.frontend;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -40,6 +40,7 @@ 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.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
|
import com.kingsrook.qqq.backend.core.model.metadata.help.QHelpContent;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareableTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareableTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.ExposedJoin;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.ExposedJoin;
|
||||||
@ -61,7 +62,7 @@ public class QFrontendTableMetaData
|
|||||||
private String label;
|
private String label;
|
||||||
private boolean isHidden;
|
private boolean isHidden;
|
||||||
private String primaryKeyField;
|
private String primaryKeyField;
|
||||||
private String iconName;
|
private QIcon icon;
|
||||||
|
|
||||||
private Map<String, QFrontendFieldMetaData> fields;
|
private Map<String, QFrontendFieldMetaData> fields;
|
||||||
private List<QFieldSection> sections;
|
private List<QFieldSection> sections;
|
||||||
@ -156,10 +157,7 @@ public class QFrontendTableMetaData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tableMetaData.getIcon() != null)
|
this.icon = tableMetaData.getIcon();
|
||||||
{
|
|
||||||
this.iconName = tableMetaData.getIcon().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
setCapabilities(backendForTable, tableMetaData);
|
setCapabilities(backendForTable, tableMetaData);
|
||||||
|
|
||||||
@ -185,7 +183,7 @@ public class QFrontendTableMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private void setCapabilities(QBackendMetaData backend, QTableMetaData table)
|
private void setCapabilities(QBackendMetaData backend, QTableMetaData table)
|
||||||
{
|
{
|
||||||
Set<Capability> enabledCapabilities = new HashSet<>();
|
Set<Capability> enabledCapabilities = new LinkedHashSet<>();
|
||||||
for(Capability capability : Capability.values())
|
for(Capability capability : Capability.values())
|
||||||
{
|
{
|
||||||
if(table.isCapabilityEnabled(backend, capability))
|
if(table.isCapabilityEnabled(backend, capability))
|
||||||
@ -275,7 +273,7 @@ public class QFrontendTableMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return iconName;
|
return (icon == null ? null : icon.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -397,4 +395,16 @@ public class QFrontendTableMetaData
|
|||||||
{
|
{
|
||||||
return helpContents;
|
return helpContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for icon
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public QIcon getIcon()
|
||||||
|
{
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.processes;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Possible ways the steps of a process can flow.
|
||||||
|
**
|
||||||
|
** LINEAR - (the default) - the list of steps in the process are executed in-order
|
||||||
|
**
|
||||||
|
** STATE_MACHINE - concept of "states", each which has a backend & frontend step;
|
||||||
|
** a backend step can (must?) set the field "stepState" (or "nextStepName") to
|
||||||
|
** say what the next (frontend) step is.
|
||||||
|
*******************************************************************************/
|
||||||
|
public enum ProcessStepFlow
|
||||||
|
{
|
||||||
|
LINEAR,
|
||||||
|
STATE_MACHINE
|
||||||
|
}
|
@ -47,6 +47,8 @@ public class QFrontendStepMetaData extends QStepMetaData
|
|||||||
private List<QFieldMetaData> recordListFields;
|
private List<QFieldMetaData> recordListFields;
|
||||||
private Map<String, QFieldMetaData> formFieldMap;
|
private Map<String, QFieldMetaData> formFieldMap;
|
||||||
|
|
||||||
|
private String format;
|
||||||
|
|
||||||
private List<QHelpContent> helpContents;
|
private List<QHelpContent> helpContents;
|
||||||
|
|
||||||
|
|
||||||
@ -403,4 +405,35 @@ public class QFrontendStepMetaData extends QStepMetaData
|
|||||||
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, this.helpContents);
|
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, this.helpContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getFormat()
|
||||||
|
{
|
||||||
|
return (this.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFormat(String format)
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for format
|
||||||
|
*******************************************************************************/
|
||||||
|
public QFrontendStepMetaData withFormat(String format)
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
private Integer minInputRecords = null;
|
private Integer minInputRecords = null;
|
||||||
private Integer maxInputRecords = null;
|
private Integer maxInputRecords = null;
|
||||||
|
|
||||||
|
private ProcessStepFlow stepFlow = ProcessStepFlow.LINEAR;
|
||||||
private List<QStepMetaData> stepList; // these are the steps that are ran, by-default, in the order they are ran in
|
private List<QStepMetaData> stepList; // these are the steps that are ran, by-default, in the order they are ran in
|
||||||
private Map<String, QStepMetaData> steps; // this is the full map of possible steps
|
private Map<String, QStepMetaData> steps; // this is the full map of possible steps
|
||||||
|
|
||||||
@ -213,11 +214,10 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/***************************************************************************
|
||||||
** add a step to the stepList and map
|
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
***************************************************************************/
|
||||||
public QProcessMetaData addStep(QStepMetaData step)
|
public QProcessMetaData withStep(QStepMetaData step)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if(this.stepList != null)
|
if(this.stepList != null)
|
||||||
@ -231,11 +231,23 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** add a step to the stepList and map
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Deprecated(since = "withStep was added")
|
||||||
|
public QProcessMetaData addStep(QStepMetaData step)
|
||||||
|
{
|
||||||
|
return (withStep(step));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** add a step to the stepList (at the specified index) and the step map
|
** add a step to the stepList (at the specified index) and the step map
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QProcessMetaData addStep(int index, QStepMetaData step)
|
public QProcessMetaData withStep(int index, QStepMetaData step)
|
||||||
{
|
{
|
||||||
if(this.stepList == null)
|
if(this.stepList == null)
|
||||||
{
|
{
|
||||||
@ -260,11 +272,23 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** add a step to the stepList (at the specified index) and the step map
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Deprecated(since = "withStep was added")
|
||||||
|
public QProcessMetaData addStep(int index, QStepMetaData step)
|
||||||
|
{
|
||||||
|
return (withStep(index, step));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** add a step ONLY to the step map - NOT the list w/ default execution order.
|
** add a step ONLY to the step map - NOT the list w/ default execution order.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QProcessMetaData addOptionalStep(QStepMetaData step)
|
public QProcessMetaData withOptionalStep(QStepMetaData step)
|
||||||
{
|
{
|
||||||
if(this.steps == null)
|
if(this.steps == null)
|
||||||
{
|
{
|
||||||
@ -283,6 +307,18 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** add a step ONLY to the step map - NOT the list w/ default execution order.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Deprecated(since = "withOptionalStep was added")
|
||||||
|
public QProcessMetaData addOptionalStep(QStepMetaData step)
|
||||||
|
{
|
||||||
|
return (withOptionalStep(step));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for stepList
|
** Setter for stepList
|
||||||
**
|
**
|
||||||
@ -299,7 +335,26 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QStepMetaData getStep(String stepName)
|
public QStepMetaData getStep(String stepName)
|
||||||
{
|
{
|
||||||
return (steps.get(stepName));
|
if(steps.containsKey(stepName))
|
||||||
|
{
|
||||||
|
return steps.get(stepName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(QStepMetaData step : steps.values())
|
||||||
|
{
|
||||||
|
if(step instanceof QStateMachineStep stateMachineStep)
|
||||||
|
{
|
||||||
|
for(QStepMetaData subStep : stateMachineStep.getSubSteps())
|
||||||
|
{
|
||||||
|
if(subStep.getName().equals(stepName))
|
||||||
|
{
|
||||||
|
return (subStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -780,4 +835,35 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for stepFlow
|
||||||
|
*******************************************************************************/
|
||||||
|
public ProcessStepFlow getStepFlow()
|
||||||
|
{
|
||||||
|
return (this.stepFlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for stepFlow
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setStepFlow(ProcessStepFlow stepFlow)
|
||||||
|
{
|
||||||
|
this.stepFlow = stepFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for stepFlow
|
||||||
|
*******************************************************************************/
|
||||||
|
public QProcessMetaData withStepFlow(ProcessStepFlow stepFlow)
|
||||||
|
{
|
||||||
|
this.stepFlow = stepFlow;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.processes;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** A step for a state-machine flow based Process.
|
||||||
|
**
|
||||||
|
** Consists of 1 or 2 sub-steps, which are frontend and/or backend.
|
||||||
|
*******************************************************************************/
|
||||||
|
public class QStateMachineStep extends QStepMetaData
|
||||||
|
{
|
||||||
|
private List<QStepMetaData> subSteps = new ArrayList<>();
|
||||||
|
|
||||||
|
private String defaultNextStepName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private QStateMachineStep(List<QStepMetaData> subSteps)
|
||||||
|
{
|
||||||
|
setStepType("stateMachine");
|
||||||
|
this.subSteps.addAll(subSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static QStateMachineStep frontendOnly(String name, QFrontendStepMetaData frontendStepMetaData)
|
||||||
|
{
|
||||||
|
if(!StringUtils.hasContent(frontendStepMetaData.getName()))
|
||||||
|
{
|
||||||
|
frontendStepMetaData.setName(name + ".frontend");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new QStateMachineStep(List.of(frontendStepMetaData)).withName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static QStateMachineStep backendOnly(String name, QBackendStepMetaData backendStepMetaData)
|
||||||
|
{
|
||||||
|
if(!StringUtils.hasContent(backendStepMetaData.getName()))
|
||||||
|
{
|
||||||
|
backendStepMetaData.setName(name + ".backend");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new QStateMachineStep(List.of(backendStepMetaData)).withName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static QStateMachineStep frontendThenBackend(String name, QFrontendStepMetaData frontendStepMetaData, QBackendStepMetaData backendStepMetaData)
|
||||||
|
{
|
||||||
|
if(!StringUtils.hasContent(frontendStepMetaData.getName()))
|
||||||
|
{
|
||||||
|
frontendStepMetaData.setName(name + ".frontend");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!StringUtils.hasContent(backendStepMetaData.getName()))
|
||||||
|
{
|
||||||
|
backendStepMetaData.setName(name + ".backend");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new QStateMachineStep(List.of(frontendStepMetaData, backendStepMetaData)).withName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QStateMachineStep withName(String name)
|
||||||
|
{
|
||||||
|
super.withName(name);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QStateMachineStep withLabel(String label)
|
||||||
|
{
|
||||||
|
super.withLabel(label);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for subSteps
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<QStepMetaData> getSubSteps()
|
||||||
|
{
|
||||||
|
return subSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for defaultNextStepName
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getDefaultNextStepName()
|
||||||
|
{
|
||||||
|
return (this.defaultNextStepName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for defaultNextStepName
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setDefaultNextStepName(String defaultNextStepName)
|
||||||
|
{
|
||||||
|
this.defaultNextStepName = defaultNextStepName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for defaultNextStepName
|
||||||
|
*******************************************************************************/
|
||||||
|
public QStateMachineStep withDefaultNextStepName(String defaultNextStepName)
|
||||||
|
{
|
||||||
|
this.defaultNextStepName = defaultNextStepName;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Get a list of all of the input fields used by this step (all of its sub-steps)
|
||||||
|
*******************************************************************************/
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public List<QFieldMetaData> getInputFields()
|
||||||
|
{
|
||||||
|
List<QFieldMetaData> rs = new ArrayList<>();
|
||||||
|
for(QStepMetaData subStep : subSteps)
|
||||||
|
{
|
||||||
|
rs.addAll(subStep.getInputFields());
|
||||||
|
}
|
||||||
|
return (rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.sharing;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.sharing.ShareScope;
|
import com.kingsrook.qqq.backend.core.processes.implementations.sharing.ShareScope;
|
||||||
|
@ -26,13 +26,13 @@ import java.io.Serializable;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
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.fields.QFieldType;
|
||||||
@ -114,7 +114,7 @@ public class ScheduledReportSyncToScheduledJobProcess extends AbstractTableSyncT
|
|||||||
scheduledJob = new ScheduledJob();
|
scheduledJob = new ScheduledJob();
|
||||||
scheduledJob.setLabel("Scheduled Report " + scheduledReport.getId());
|
scheduledJob.setLabel("Scheduled Report " + scheduledReport.getId());
|
||||||
scheduledJob.setDescription("Job to run Scheduled Report Id " + scheduledReport.getId()
|
scheduledJob.setDescription("Job to run Scheduled Report Id " + scheduledReport.getId()
|
||||||
+ " (which runs Report Id " + scheduledReport.getSavedReportId() + ")");
|
+ " (which runs Report Id " + scheduledReport.getSavedReportId() + ")");
|
||||||
scheduledJob.setSchedulerName(runBackendStepInput.getValueString(SCHEDULER_NAME_FIELD_NAME));
|
scheduledJob.setSchedulerName(runBackendStepInput.getValueString(SCHEDULER_NAME_FIELD_NAME));
|
||||||
scheduledJob.setType(ScheduledJobType.PROCESS.name());
|
scheduledJob.setType(ScheduledJobType.PROCESS.name());
|
||||||
scheduledJob.setForeignKeyType(getScheduledJobForeignKeyType());
|
scheduledJob.setForeignKeyType(getScheduledJobForeignKeyType());
|
||||||
|
@ -36,7 +36,6 @@ import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
|||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
@ -47,6 +46,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.NowWithOffset;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.NowWithOffset;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.HtmlWrapper;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.HtmlWrapper;
|
||||||
@ -158,8 +158,8 @@ public class HealBadRecordAutomationStatusesProcessStep implements BackendStep,
|
|||||||
@Override
|
@Override
|
||||||
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
|
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
|
||||||
{
|
{
|
||||||
int recordsUpdated = 0;
|
int recordsUpdated = 0;
|
||||||
boolean isReview = "preview".equals(runBackendStepInput.getStepName());
|
boolean isReview = "preview".equals(runBackendStepInput.getStepName());
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// if a table name is given, validate it, and run for just that table //
|
// if a table name is given, validate it, and run for just that table //
|
||||||
|
@ -28,9 +28,9 @@ import com.kingsrook.qqq.backend.core.actions.automation.polling.PollingAutomati
|
|||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.automation.QAutomationProviderMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
|
@ -176,9 +176,9 @@ public class StreamedETLExecuteStep extends BaseStreamedETLStep implements Backe
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(postRunOutput.getUpdatedFrontendStepList() != null)
|
if(postRunOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(postRunOutput.getUpdatedFrontendStepList());
|
runBackendStepOutput.setProcessMetaDataAdjustment(postRunOutput.getProcessMetaDataAdjustment());
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -281,10 +281,10 @@ public class StreamedETLExecuteStep extends BaseStreamedETLStep implements Backe
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(streamedBackendStepOutput.getUpdatedFrontendStepList() != null)
|
if(streamedBackendStepOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.getProcessState().setStepList(streamedBackendStepOutput.getProcessState().getStepList());
|
runBackendStepOutput.getProcessState().setStepList(streamedBackendStepOutput.getProcessState().getStepList());
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(streamedBackendStepOutput.getUpdatedFrontendStepList());
|
runBackendStepOutput.getProcessState().setProcessMetaDataAdjustment(streamedBackendStepOutput.getProcessMetaDataAdjustment());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
@ -299,10 +299,10 @@ public class StreamedETLExecuteStep extends BaseStreamedETLStep implements Backe
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(streamedBackendStepOutput.getUpdatedFrontendStepList() != null)
|
if(streamedBackendStepOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.getProcessState().setStepList(streamedBackendStepOutput.getProcessState().getStepList());
|
runBackendStepOutput.getProcessState().setStepList(streamedBackendStepOutput.getProcessState().getStepList());
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(streamedBackendStepOutput.getUpdatedFrontendStepList());
|
runBackendStepOutput.getProcessState().setProcessMetaDataAdjustment(streamedBackendStepOutput.getProcessMetaDataAdjustment());
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -148,9 +148,9 @@ public class StreamedETLPreviewStep extends BaseStreamedETLStep implements Backe
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(postRunOutput.getUpdatedFrontendStepList() != null)
|
if(postRunOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(postRunOutput.getUpdatedFrontendStepList());
|
runBackendStepOutput.setProcessMetaDataAdjustment(postRunOutput.getProcessMetaDataAdjustment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,10 +219,9 @@ public class StreamedETLPreviewStep extends BaseStreamedETLStep implements Backe
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(streamedBackendStepOutput.getUpdatedFrontendStepList() != null)
|
if(streamedBackendStepOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.getProcessState().setStepList(streamedBackendStepOutput.getProcessState().getStepList());
|
runBackendStepOutput.getProcessState().setProcessMetaDataAdjustment(streamedBackendStepOutput.getProcessMetaDataAdjustment());
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(streamedBackendStepOutput.getUpdatedFrontendStepList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
@ -145,9 +145,9 @@ public class StreamedETLValidateStep extends BaseStreamedETLStep implements Back
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(postRunOutput.getUpdatedFrontendStepList() != null)
|
if(postRunOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(postRunOutput.getUpdatedFrontendStepList());
|
runBackendStepOutput.setProcessMetaDataAdjustment(postRunOutput.getProcessMetaDataAdjustment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,10 +183,9 @@ public class StreamedETLValidateStep extends BaseStreamedETLStep implements Back
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// propagate data from inner-step state to process-level step state //
|
// propagate data from inner-step state to process-level step state //
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
if(streamedBackendStepOutput.getUpdatedFrontendStepList() != null)
|
if(streamedBackendStepOutput.getProcessMetaDataAdjustment() != null)
|
||||||
{
|
{
|
||||||
runBackendStepOutput.getProcessState().setStepList(streamedBackendStepOutput.getProcessState().getStepList());
|
runBackendStepOutput.setProcessMetaDataAdjustment(streamedBackendStepOutput.getProcessMetaDataAdjustment());
|
||||||
runBackendStepOutput.setUpdatedFrontendStepList(streamedBackendStepOutput.getUpdatedFrontendStepList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -23,10 +23,10 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
@ -58,7 +58,7 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
|
|||||||
public static final String FIELD_NAME_STORAGE_TABLE_NAME = "storageTableName";
|
public static final String FIELD_NAME_STORAGE_TABLE_NAME = "storageTableName";
|
||||||
public static final String FIELD_NAME_REPORT_FORMAT = "reportFormat";
|
public static final String FIELD_NAME_REPORT_FORMAT = "reportFormat";
|
||||||
public static final String FIELD_NAME_EMAIL_ADDRESS = "reportDestinationEmailAddress";
|
public static final String FIELD_NAME_EMAIL_ADDRESS = "reportDestinationEmailAddress";
|
||||||
public static final String FIELD_NAME_EMAIL_SUBJECT = "emailSubject";
|
public static final String FIELD_NAME_EMAIL_SUBJECT = "emailSubject";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ package com.kingsrook.qqq.backend.core.processes.implementations.savedreports;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
|
@ -27,12 +27,12 @@ import java.util.Objects;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.delete.DeleteOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
@ -87,9 +87,9 @@ public class DeleteSharedRecordProcess implements BackendStep, MetaDataProducerI
|
|||||||
@Override
|
@Override
|
||||||
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
|
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
|
||||||
{
|
{
|
||||||
String tableName = runBackendStepInput.getValueString("tableName");
|
String tableName = runBackendStepInput.getValueString("tableName");
|
||||||
String recordIdString = runBackendStepInput.getValueString("recordId");
|
String recordIdString = runBackendStepInput.getValueString("recordId");
|
||||||
Integer shareId = runBackendStepInput.getValueInteger("shareId");
|
Integer shareId = runBackendStepInput.getValueInteger("shareId");
|
||||||
|
|
||||||
Objects.requireNonNull(tableName, "Missing required input: tableName");
|
Objects.requireNonNull(tableName, "Missing required input: tableName");
|
||||||
Objects.requireNonNull(recordIdString, "Missing required input: recordId");
|
Objects.requireNonNull(recordIdString, "Missing required input: recordId");
|
||||||
|
@ -28,12 +28,12 @@ import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
@ -37,7 +37,6 @@ import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
|||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||||
@ -47,6 +46,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
@ -134,7 +134,7 @@ public class GetSharedRecordsProcess implements BackendStep, MetaDataProducerInt
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// iterate results, building QRecords to output - note - we'll need to collect ids, then look them up in audience-source tables //
|
// iterate results, building QRecords to output - note - we'll need to collect ids, then look them up in audience-source tables //
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
ArrayList<QRecord> resultList = new ArrayList<>();
|
ArrayList<QRecord> resultList = new ArrayList<>();
|
||||||
ListingHash<String, Serializable> audienceIds = new ListingHash<>();
|
ListingHash<String, Serializable> audienceIds = new ListingHash<>();
|
||||||
for(QRecord record : queryOutput.getRecords())
|
for(QRecord record : queryOutput.getRecords())
|
||||||
{
|
{
|
||||||
|
@ -32,13 +32,13 @@ import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
|||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
@ -24,7 +24,7 @@ package com.kingsrook.qqq.backend.core.processes.locks;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerMultiOutput;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerMultiOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||||
|
@ -25,9 +25,9 @@ package com.kingsrook.qqq.backend.core.scheduler.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
|
@ -25,9 +25,9 @@ package com.kingsrook.qqq.backend.core.scheduler.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
|
@ -25,9 +25,9 @@ package com.kingsrook.qqq.backend.core.scheduler.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
|
@ -25,9 +25,9 @@ package com.kingsrook.qqq.backend.core.scheduler.quartz.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
|
@ -25,10 +25,10 @@ package com.kingsrook.qqq.backend.core.scheduler.quartz.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerMultiOutput;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerMultiOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
@ -25,9 +25,9 @@ package com.kingsrook.qqq.backend.core.scheduler.quartz.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode.WidgetHtmlLine;
|
||||||
|
@ -25,10 +25,10 @@ package com.kingsrook.qqq.backend.core.scheduler.quartz.processes;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerMultiOutput;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerMultiOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.reflect.ClassPath;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Utilities for reading classes - e.g., finding all in a package
|
||||||
|
*******************************************************************************/
|
||||||
|
@SuppressWarnings("ALL") // the api we're using here, from google, is marked Beta
|
||||||
|
public class ClassPathUtils
|
||||||
|
{
|
||||||
|
private static ImmutableSet<ClassPath.ClassInfo> topLevelClasses;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** from https://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static List<Class<?>> getClassesInPackage(String packageName) throws IOException
|
||||||
|
{
|
||||||
|
List<Class<?>> classes = new ArrayList<>();
|
||||||
|
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
|
|
||||||
|
for(ClassPath.ClassInfo info : getTopLevelClasses(loader))
|
||||||
|
{
|
||||||
|
if(info.getName().startsWith(packageName))
|
||||||
|
{
|
||||||
|
classes.add(info.load());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static ImmutableSet<ClassPath.ClassInfo> getTopLevelClasses(ClassLoader loader) throws IOException
|
||||||
|
{
|
||||||
|
if(topLevelClasses == null)
|
||||||
|
{
|
||||||
|
topLevelClasses = ClassPath.from(loader).getTopLevelClasses();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (topLevelClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static void clearTopLevelClassCache()
|
||||||
|
{
|
||||||
|
topLevelClasses = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -31,9 +31,13 @@ import java.util.stream.Collectors;
|
|||||||
import com.kingsrook.qqq.backend.core.BaseTest;
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.QCollectingLogger;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNode;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNodeType;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.AppTreeNodeType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendAppMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendAppMetaData;
|
||||||
@ -41,9 +45,13 @@ import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendProcessMe
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendReportMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendReportMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendWidgetMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.frontend.QFrontendWidgetMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.DenyBehavior;
|
import com.kingsrook.qqq.backend.core.model.metadata.permissions.DenyBehavior;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.PermissionLevel;
|
import com.kingsrook.qqq.backend.core.model.metadata.permissions.PermissionLevel;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
|
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
|
||||||
|
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.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -350,4 +358,118 @@ class MetaDataActionTest extends BaseTest
|
|||||||
assertTrue(personMemoryTable.getDeletePermission());
|
assertTrue(personMemoryTable.getDeletePermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testFilter() throws QException
|
||||||
|
{
|
||||||
|
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(MetaDataAction.class);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// run default version, and assert tables are found //
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
MetaDataOutput result = new MetaDataAction().execute(new MetaDataInput());
|
||||||
|
assertFalse(result.getTables().isEmpty(), "should be some tables");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// run again (with the same instance as before) to assert about memoization of the filter based on the QInstance //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
new MetaDataAction().execute(new MetaDataInput());
|
||||||
|
assertThat(collectingLogger.getCollectedMessages()).filteredOn(clm -> clm.getMessage().contains("Using new default")).hasSize(1);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
// set up new instance to use a custom filter, to deny all //
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
QInstance instance = TestUtils.defineInstance();
|
||||||
|
instance.setMetaDataFilter(new QCodeReference(DenyAllFilter.class));
|
||||||
|
reInitInstanceInContext(instance);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// re-run, and assert all tables are filtered away //
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
result = new MetaDataAction().execute(new MetaDataInput());
|
||||||
|
assertTrue(result.getTables().isEmpty(), "should be no tables");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// run again (with the same instance as before) to assert about memoization of the filter based on the QInstance //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
new MetaDataAction().execute(new MetaDataInput());
|
||||||
|
assertThat(collectingLogger.getCollectedMessages()).filteredOn(clm -> clm.getMessage().contains("filter of type: DenyAllFilter")).hasSize(1);
|
||||||
|
|
||||||
|
QLogger.deactivateCollectingLoggerForClass(MetaDataAction.class);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// run now with the AllowAllFilter, confirm we get tables //
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
instance = TestUtils.defineInstance();
|
||||||
|
instance.setMetaDataFilter(new QCodeReference(AllowAllMetaDataFilter.class));
|
||||||
|
reInitInstanceInContext(instance);
|
||||||
|
result = new MetaDataAction().execute(new MetaDataInput());
|
||||||
|
assertFalse(result.getTables().isEmpty(), "should be some tables");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static class DenyAllFilter implements MetaDataFilterInterface
|
||||||
|
{
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowTable(MetaDataInput input, QTableMetaData table)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowProcess(MetaDataInput input, QProcessMetaData process)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowReport(MetaDataInput input, QReportMetaData report)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowApp(MetaDataInput input, QAppMetaData app)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean allowWidget(MetaDataInput input, QWidgetMetaDataInterface widget)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.processes;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReferenceLambda;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.ProcessStepFlow;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStateMachineStep;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for RunProcessAction
|
||||||
|
*******************************************************************************/
|
||||||
|
class RunProcessActionTest extends BaseTest
|
||||||
|
{
|
||||||
|
private static List<String> log = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach()
|
||||||
|
{
|
||||||
|
log.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testStateMachineTwoBackendSteps() throws QException
|
||||||
|
{
|
||||||
|
QProcessMetaData process = new QProcessMetaData().withName("test")
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
// two-steps - a, points at b; b has no next-step, so it exits //
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
.addStep(QStateMachineStep.backendOnly("a", new QBackendStepMetaData().withName("aBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepA");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("b");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.backendOnly("b", new QBackendStepMetaData().withName("bBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepB");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.withStepFlow(ProcessStepFlow.STATE_MACHINE);
|
||||||
|
|
||||||
|
QContext.getQInstance().addProcess(process);
|
||||||
|
|
||||||
|
RunProcessInput input = new RunProcessInput();
|
||||||
|
input.setProcessName("test");
|
||||||
|
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
|
||||||
|
|
||||||
|
RunProcessOutput runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertEquals(List.of("in StepA", "in StepB"), log);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testStateMachineTwoFrontendOnlySteps() throws QException
|
||||||
|
{
|
||||||
|
QProcessMetaData process = new QProcessMetaData().withName("test")
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.frontendOnly("a", new QFrontendStepMetaData().withName("aFrontend")).withDefaultNextStepName("b"))
|
||||||
|
.addStep(QStateMachineStep.frontendOnly("b", new QFrontendStepMetaData().withName("bFrontend")))
|
||||||
|
|
||||||
|
.withStepFlow(ProcessStepFlow.STATE_MACHINE);
|
||||||
|
|
||||||
|
QContext.getQInstance().addProcess(process);
|
||||||
|
|
||||||
|
RunProcessInput input = new RunProcessInput();
|
||||||
|
input.setProcessName("test");
|
||||||
|
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
|
||||||
|
|
||||||
|
RunProcessOutput runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName())
|
||||||
|
.isPresent().get()
|
||||||
|
.isEqualTo("aFrontend");
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// resume after a, go to b //
|
||||||
|
/////////////////////////////
|
||||||
|
input.setStartAfterStep("aFrontend");
|
||||||
|
runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName())
|
||||||
|
.isPresent().get()
|
||||||
|
.isEqualTo("bFrontend");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testStateMachineOneBackendStepReferencingItselfDoesNotInfiniteLoop() throws QException
|
||||||
|
{
|
||||||
|
QProcessMetaData process = new QProcessMetaData().withName("test")
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
// set up step that always points back at itself. //
|
||||||
|
// since it never goes to the frontend, it'll stack overflow //
|
||||||
|
// (though we'll catch it ourselves before JVM does) //
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
.addStep(QStateMachineStep.backendOnly("a", new QBackendStepMetaData().withName("aBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepA");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("a");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.withStepFlow(ProcessStepFlow.STATE_MACHINE);
|
||||||
|
|
||||||
|
QContext.getQInstance().addProcess(process);
|
||||||
|
|
||||||
|
RunProcessInput input = new RunProcessInput();
|
||||||
|
input.setProcessName("test");
|
||||||
|
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> new RunProcessAction().execute(input))
|
||||||
|
.isInstanceOf(QException.class)
|
||||||
|
.hasMessageContaining("maxStateMachineProcessStepFlowStackDepth of 20");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// make sure we can set a custom max-stack-depth //
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
input.addValue("maxStateMachineProcessStepFlowStackDepth", 5);
|
||||||
|
assertThatThrownBy(() -> new RunProcessAction().execute(input))
|
||||||
|
.isInstanceOf(QException.class)
|
||||||
|
.hasMessageContaining("maxStateMachineProcessStepFlowStackDepth of 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testStateMachineTwoBackendStepsReferencingEachOtherDoesNotInfiniteLoop() throws QException
|
||||||
|
{
|
||||||
|
QProcessMetaData process = new QProcessMetaData().withName("test")
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
// set up two steps that always points back at each other. //
|
||||||
|
// since it never goes to the frontend, it'll stack overflow //
|
||||||
|
// (though we'll catch it ourselves before JVM does) //
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
.addStep(QStateMachineStep.backendOnly("a", new QBackendStepMetaData().withName("aBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepA");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("b");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.backendOnly("b", new QBackendStepMetaData().withName("bBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepB");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("a");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.withStepFlow(ProcessStepFlow.STATE_MACHINE);
|
||||||
|
|
||||||
|
QContext.getQInstance().addProcess(process);
|
||||||
|
|
||||||
|
RunProcessInput input = new RunProcessInput();
|
||||||
|
input.setProcessName("test");
|
||||||
|
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> new RunProcessAction().execute(input))
|
||||||
|
.isInstanceOf(QException.class)
|
||||||
|
.hasMessageContaining("maxStateMachineProcessStepFlowStackDepth of 20");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// make sure we can set a custom max-stack-depth //
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
input.addValue("maxStateMachineProcessStepFlowStackDepth", 5);
|
||||||
|
assertThatThrownBy(() -> new RunProcessAction().execute(input))
|
||||||
|
.isInstanceOf(QException.class)
|
||||||
|
.hasMessageContaining("maxStateMachineProcessStepFlowStackDepth of 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testStateSequenceOfFrontendAndBackendSteps() throws QException
|
||||||
|
{
|
||||||
|
QProcessMetaData process = new QProcessMetaData().withName("test")
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.frontendThenBackend("a",
|
||||||
|
new QFrontendStepMetaData().withName("aFrontend"),
|
||||||
|
new QBackendStepMetaData().withName("aBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepA");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("b");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.frontendThenBackend("b",
|
||||||
|
new QFrontendStepMetaData().withName("bFrontend"),
|
||||||
|
new QBackendStepMetaData().withName("bBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepB");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("c");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.frontendThenBackend("c",
|
||||||
|
new QFrontendStepMetaData().withName("cFrontend"),
|
||||||
|
new QBackendStepMetaData().withName("cBackend")
|
||||||
|
.withCode(new QCodeReferenceLambda<BackendStep>((runBackendStepInput, runBackendStepOutput) ->
|
||||||
|
{
|
||||||
|
log.add("in StepC");
|
||||||
|
runBackendStepOutput.getProcessState().setNextStepName("d");
|
||||||
|
}))))
|
||||||
|
|
||||||
|
.addStep(QStateMachineStep.frontendOnly("d",
|
||||||
|
new QFrontendStepMetaData().withName("dFrontend")))
|
||||||
|
|
||||||
|
.withStepFlow(ProcessStepFlow.STATE_MACHINE);
|
||||||
|
|
||||||
|
QContext.getQInstance().addProcess(process);
|
||||||
|
|
||||||
|
RunProcessInput input = new RunProcessInput();
|
||||||
|
input.setProcessName("test");
|
||||||
|
input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
// start the process - we should be sent to aFrontend //
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
RunProcessOutput runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName())
|
||||||
|
.isPresent().get()
|
||||||
|
.isEqualTo("aFrontend");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// resume after aFrontend - we should run StepA (backend), and then be sent to bFrontend //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
input.setStartAfterStep("aFrontend");
|
||||||
|
runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertEquals(List.of("in StepA"), log);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName())
|
||||||
|
.isPresent().get()
|
||||||
|
.isEqualTo("bFrontend");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// resume after bFrontend - we should run StepB (backend), and then be sent to cFrontend //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
input.setStartAfterStep("bFrontend");
|
||||||
|
runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertEquals(List.of("in StepA", "in StepB"), log);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName())
|
||||||
|
.isPresent().get()
|
||||||
|
.isEqualTo("cFrontend");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// resume after cFrontend - we should run StepC (backend), and then be sent to dFrontend //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
input.setStartAfterStep("cFrontend");
|
||||||
|
runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertEquals(List.of("in StepA", "in StepB", "in StepC"), log);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName())
|
||||||
|
.isPresent().get()
|
||||||
|
.isEqualTo("dFrontend");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if we resume again here, we'll be past the end of the process, so no next-step //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
input.setStartAfterStep("dFrontend");
|
||||||
|
runProcessOutput = new RunProcessAction().execute(input);
|
||||||
|
assertEquals(List.of("in StepA", "in StepB", "in StepC"), log);
|
||||||
|
assertThat(runProcessOutput.getProcessState().getNextStepName()).isEmpty();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.reporting;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for DistinctFilteringRecordPipe
|
||||||
|
*******************************************************************************/
|
||||||
|
class DistinctFilteringRecordPipeTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testSingleFieldKey() throws QException
|
||||||
|
{
|
||||||
|
DistinctFilteringRecordPipe pipe = new DistinctFilteringRecordPipe(new UniqueKey("id"));
|
||||||
|
pipe.addRecord(new QRecord().withValue("id", 1));
|
||||||
|
pipe.addRecord(new QRecord().withValue("id", 1));
|
||||||
|
assertEquals(1, pipe.consumeAvailableRecords().size());
|
||||||
|
|
||||||
|
pipe.addRecord(new QRecord().withValue("id", 1));
|
||||||
|
assertEquals(0, pipe.consumeAvailableRecords().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testMultiFieldKey() throws QException
|
||||||
|
{
|
||||||
|
DistinctFilteringRecordPipe pipe = new DistinctFilteringRecordPipe(new UniqueKey("type", "name"));
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// add 3 distinct records //
|
||||||
|
////////////////////////////
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 1).withValue("name", "A"));
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 1).withValue("name", "B"));
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 2).withValue("name", "B"));
|
||||||
|
assertEquals(3, pipe.consumeAvailableRecords().size());
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
// now re-add those 3 (should all be discarded) plus one new one //
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 1).withValue("name", "A"));
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 1).withValue("name", "B"));
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 2).withValue("name", "B"));
|
||||||
|
pipe.addRecord(new QRecord().withValue("type", 2).withValue("name", "A"));
|
||||||
|
assertEquals(1, pipe.consumeAvailableRecords().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -80,6 +81,7 @@ import org.junit.jupiter.api.AfterEach;
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
@ -340,6 +342,16 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private String runToString(ReportFormat reportFormat, String reportName) throws Exception
|
private String runToString(ReportFormat reportFormat, String reportName) throws Exception
|
||||||
|
{
|
||||||
|
return (runToString(reportFormat, reportName, Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now())));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private String runToString(ReportFormat reportFormat, String reportName, Map<String, Serializable> inputValues) throws Exception
|
||||||
{
|
{
|
||||||
String name = "/tmp/report." + reportFormat.getExtension();
|
String name = "/tmp/report." + reportFormat.getExtension();
|
||||||
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
try(FileOutputStream fileOutputStream = new FileOutputStream(name))
|
||||||
@ -347,7 +359,7 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
ReportInput reportInput = new ReportInput();
|
ReportInput reportInput = new ReportInput();
|
||||||
reportInput.setReportName(reportName);
|
reportInput.setReportName(reportName);
|
||||||
reportInput.setReportDestination(new ReportDestination().withReportFormat(reportFormat).withReportOutputStream(fileOutputStream));
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(reportFormat).withReportOutputStream(fileOutputStream));
|
||||||
reportInput.setInputValues(Map.of("startDate", LocalDate.of(1970, Month.MAY, 15), "endDate", LocalDate.now()));
|
reportInput.setInputValues(inputValues);
|
||||||
new GenerateReportAction().execute(reportInput);
|
new GenerateReportAction().execute(reportInput);
|
||||||
System.out.println("Wrote File: " + name);
|
System.out.println("Wrote File: " + name);
|
||||||
return (FileUtils.readFileToString(new File(name), StandardCharsets.UTF_8));
|
return (FileUtils.readFileToString(new File(name), StandardCharsets.UTF_8));
|
||||||
@ -976,4 +988,55 @@ public class GenerateReportActionTest extends BaseTest
|
|||||||
assertThat(row.get("Home State Name")).isEqualTo("IL");
|
assertThat(row.get("Home State Name")).isEqualTo("IL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testFilterMissingValue() throws Exception
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// define a report in the instance, with an input field - then we'll run it w/o supplying the value //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
QReportMetaData report = new QReportMetaData()
|
||||||
|
.withName(REPORT_NAME)
|
||||||
|
.withDataSources(List.of(
|
||||||
|
new QReportDataSource()
|
||||||
|
.withName("persons")
|
||||||
|
.withSourceTable(TestUtils.TABLE_NAME_PERSON_MEMORY)
|
||||||
|
.withQueryFilter(new QQueryFilter()
|
||||||
|
.withCriteria(new QFilterCriteria("birthDate", QCriteriaOperator.GREATER_THAN, List.of("${input.startDate}"))))))
|
||||||
|
.withViews(List.of(
|
||||||
|
new QReportView()
|
||||||
|
.withName("table1")
|
||||||
|
.withLabel("Table 1")
|
||||||
|
.withDataSourceName("persons")
|
||||||
|
.withType(ReportType.TABLE)
|
||||||
|
.withColumns(List.of(new QReportField().withName("id")))
|
||||||
|
));
|
||||||
|
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
qInstance.addReport(report);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// the report should run, but with the filter removed, so it should find all (6) person records //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
insertPersonRecords(qInstance);
|
||||||
|
String json = runToString(ReportFormat.JSON, report.getName(), Collections.emptyMap());
|
||||||
|
JSONArray reportJsonArray = new JSONArray(json);
|
||||||
|
assertEquals(6, reportJsonArray.length());
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// re-run now, pretending to be a report that wasn't defined in meta-data, but instead was //
|
||||||
|
// ah-hoc-style, in which case, a missing input is defined as, should throw exception. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
ReportInput reportInput = new ReportInput();
|
||||||
|
report.setName(null);
|
||||||
|
reportInput.setReportMetaData(report);
|
||||||
|
reportInput.setReportDestination(new ReportDestination().withReportFormat(ReportFormat.JSON).withReportOutputStream(new ByteArrayOutputStream()));
|
||||||
|
assertThatThrownBy(() -> new GenerateReportAction().execute(reportInput))
|
||||||
|
.hasMessageContaining("Missing value for criteria on field: birthDate");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.reporting.excel.fastexcel;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import org.dhatim.fastexcel.StyleSetter;
|
||||||
|
import org.dhatim.fastexcel.Workbook;
|
||||||
|
import org.dhatim.fastexcel.Worksheet;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for BoldHeaderAndFooterFastExcelStyler
|
||||||
|
*******************************************************************************/
|
||||||
|
class BoldHeaderAndFooterFastExcelStylerTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** ... kinda just here to add test coverage to the class. I suppose, it
|
||||||
|
** makes sure there's not an NPE inside that method at least...?
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
Workbook workbook = new Workbook(new ByteArrayOutputStream(), "Test", null);
|
||||||
|
Worksheet worksheet = workbook.newWorksheet("Sheet 1");
|
||||||
|
StyleSetter headerStyle = worksheet.range(0, 0, 1, 1).style();
|
||||||
|
new BoldHeaderAndFooterFastExcelStyler().styleHeaderRow(headerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.actions.scripts;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QCodeException;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for QCodeExecutor
|
||||||
|
*******************************************************************************/
|
||||||
|
class QCodeExecutorTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testConvertJavaObject() throws QCodeException
|
||||||
|
{
|
||||||
|
Object input = new Object();
|
||||||
|
Object converted = ((QCodeExecutor) (codeReference, inputContext, executionLogger) -> null).convertJavaObject(input, null);
|
||||||
|
assertSame(input, converted);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testConvertObjectToJava() throws QCodeException
|
||||||
|
{
|
||||||
|
Object input = new Object();
|
||||||
|
Object converted = ((QCodeExecutor) (codeReference, inputContext, executionLogger) -> null).convertObjectToJava(input);
|
||||||
|
assertSame(input, converted);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.instances;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for AbstractMetaDataProducerBasedQQQApplication
|
||||||
|
*******************************************************************************/
|
||||||
|
class AbstractMetaDataProducerBasedQQQApplicationTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void test() throws QException
|
||||||
|
{
|
||||||
|
QInstance qInstance = new TestApplication().defineQInstance();
|
||||||
|
assertEquals(1, qInstance.getTables().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static class TestApplication extends AbstractMetaDataProducerBasedQQQApplication
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public String getMetaDataPackageName()
|
||||||
|
{
|
||||||
|
return getClass().getPackage().getName() + ".producers";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.instances;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for AbstractQQQApplication
|
||||||
|
*******************************************************************************/
|
||||||
|
class AbstractQQQApplicationTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void test() throws QException
|
||||||
|
{
|
||||||
|
TestApplication testApplication = new TestApplication();
|
||||||
|
QInstance qInstance = testApplication.defineQInstance();
|
||||||
|
assertEquals(1, qInstance.getTables().size());
|
||||||
|
assertTrue(qInstance.getTables().containsKey("testTable"));
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> testApplication.defineValidatedQInstance())
|
||||||
|
.hasMessageContaining("validation");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
public static class TestApplication extends AbstractQQQApplication
|
||||||
|
{
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QInstance defineQInstance() throws QException
|
||||||
|
{
|
||||||
|
QInstance qInstance = new QInstance();
|
||||||
|
qInstance.addTable(new QTableMetaData().withName("testTable"));
|
||||||
|
return (qInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -38,6 +38,7 @@ import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.dashboard.PersonsByCreateDateBarChart;
|
import com.kingsrook.qqq.backend.core.actions.dashboard.PersonsByCreateDateBarChart;
|
||||||
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.AbstractWidgetRenderer;
|
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.AbstractWidgetRenderer;
|
||||||
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.ParentWidgetRenderer;
|
import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.ParentWidgetRenderer;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.metadata.AllowAllMetaDataFilter;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.CancelProcessActionTest;
|
import com.kingsrook.qqq.backend.core.actions.processes.CancelProcessActionTest;
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.RecordPipe;
|
import com.kingsrook.qqq.backend.core.actions.reporting.RecordPipe;
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportCustomRecordSourceInterface;
|
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportCustomRecordSourceInterface;
|
||||||
@ -139,6 +140,21 @@ public class QInstanceValidatorTest extends BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testMetaDataFilter()
|
||||||
|
{
|
||||||
|
assertValidationFailureReasons((qInstance) -> qInstance.setMetaDataFilter(new QCodeReference(QInstanceValidator.class)),
|
||||||
|
"Instance metaDataFilter CodeReference is not of the expected type");
|
||||||
|
|
||||||
|
assertValidationSuccess((qInstance) -> qInstance.setMetaDataFilter(new QCodeReference(AllowAllMetaDataFilter.class)));
|
||||||
|
assertValidationSuccess((qInstance) -> qInstance.setMetaDataFilter(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test an instance with null backends - should throw.
|
** Test an instance with null backends - should throw.
|
||||||
**
|
**
|
||||||
@ -265,6 +281,38 @@ public class QInstanceValidatorTest extends BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testTableFieldInlinePossibleValueSource()
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
// make sure can't have both named and inline PVS //
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
assertValidationFailureReasonsAllowingExtraReasons((qInstance) -> qInstance.getTable("person").getField("homeStateId")
|
||||||
|
.withInlinePossibleValueSource(new QPossibleValueSource().withType(QPossibleValueSourceType.TABLE).withTableName("person")),
|
||||||
|
"both a possibleValueSourceName and an inlinePossibleValueSource");
|
||||||
|
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
// make require inline PVS to be enum type //
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
assertValidationFailureReasonsAllowingExtraReasons((qInstance) -> qInstance.getTable("person").getField("homeStateId")
|
||||||
|
.withPossibleValueSourceName(null)
|
||||||
|
.withInlinePossibleValueSource(new QPossibleValueSource().withType(QPossibleValueSourceType.TABLE)),
|
||||||
|
"must have a type of ENUM");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
// make sure validation on the inline PVS happens //
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
assertValidationFailureReasonsAllowingExtraReasons((qInstance) -> qInstance.getTable("person").getField("homeStateId")
|
||||||
|
.withPossibleValueSourceName(null)
|
||||||
|
.withInlinePossibleValueSource(new QPossibleValueSource().withType(QPossibleValueSourceType.ENUM)),
|
||||||
|
"missing enum values");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Test that if a process specifies a table that doesn't exist, that it fails.
|
** Test that if a process specifies a table that doesn't exist, that it fails.
|
||||||
**
|
**
|
||||||
@ -717,8 +765,8 @@ public class QInstanceValidatorTest extends BaseTest
|
|||||||
@Test
|
@Test
|
||||||
public void test_validateFieldWithMissingPossibleValueSource()
|
public void test_validateFieldWithMissingPossibleValueSource()
|
||||||
{
|
{
|
||||||
assertValidationFailureReasons((qInstance) -> qInstance.getTable("person").getField("homeStateId").setPossibleValueSourceName("not a real possible value source"),
|
assertValidationFailureReasonsAllowingExtraReasons((qInstance) -> qInstance.getTable("person").getField("homeStateId").setPossibleValueSourceName("not a real possible value source"),
|
||||||
"Unrecognized possibleValueSourceName");
|
"unrecognized possibleValueSourceName");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. 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.instances.producers;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class TestMetaDataProducer implements MetaDataProducerInterface<QTableMetaData>
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QTableMetaData produce(QInstance qInstance) throws QException
|
||||||
|
{
|
||||||
|
return new QTableMetaData().withName("fromProducer");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -35,6 +35,7 @@ import com.kingsrook.qqq.backend.core.utils.TestUtils;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.condition.DisabledOnOs;
|
import org.junit.jupiter.api.condition.DisabledOnOs;
|
||||||
import org.junit.jupiter.api.condition.OS;
|
import org.junit.jupiter.api.condition.OS;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -64,4 +65,19 @@ class EmailMessagingProviderTest extends BaseTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testMissingInputs()
|
||||||
|
{
|
||||||
|
assertThatThrownBy(() -> new SendMessageAction().execute(new SendMessageInput()))
|
||||||
|
.hasMessageContaining("provider name was not given");
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> new SendMessageAction().execute(new SendMessageInput().withMessagingProviderName("notFound")))
|
||||||
|
.hasMessageContaining("was not found");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.producers;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.producers;
|
|||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.MetaDataProducerInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
|
||||||
|
@ -161,9 +161,19 @@ class RenderSavedReportProcessTest extends BaseTest
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static InputStream getInputStream(RunProcessOutput runProcessOutput) throws QException
|
private static InputStream getInputStream(RunProcessOutput runProcessOutput) throws QException
|
||||||
{
|
{
|
||||||
String storageTableName = runProcessOutput.getValueString("storageTableName");
|
String storageTableName = runProcessOutput.getValueString("storageTableName");
|
||||||
String storageReference = runProcessOutput.getValueString("storageReference");
|
String storageReference = runProcessOutput.getValueString("storageReference");
|
||||||
InputStream inputStream = new MemoryStorageAction().getInputStream(new StorageInput(storageTableName).withReference(storageReference));
|
|
||||||
|
MemoryStorageAction memoryStorageAction = new MemoryStorageAction();
|
||||||
|
StorageInput storageInput = new StorageInput(storageTableName).withReference(storageReference);
|
||||||
|
InputStream inputStream = memoryStorageAction.getInputStream(storageInput);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// to help add a little bit of class-level code coverage, for the QStorageInterface, call a method //
|
||||||
|
// that has a defualt implementation in there //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
memoryStorageAction.getDownloadURL(storageInput);
|
||||||
|
|
||||||
return inputStream;
|
return inputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,11 @@
|
|||||||
<artifactId>qqq-middleware-api</artifactId>
|
<artifactId>qqq-middleware-api</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.kingsrook.qqq</groupId>
|
||||||
|
<artifactId>qqq-openapi</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.kingsrook.qqq</groupId>
|
<groupId>com.kingsrook.qqq</groupId>
|
||||||
<artifactId>qqq-middleware-picocli</artifactId>
|
<artifactId>qqq-middleware-picocli</artifactId>
|
||||||
|
@ -48,13 +48,13 @@
|
|||||||
<artifactId>qqq-middleware-javalin</artifactId>
|
<artifactId>qqq-middleware-javalin</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.kingsrook.qqq</groupId>
|
||||||
|
<artifactId>qqq-openapi</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- 3rd party deps specifically for this module -->
|
<!-- 3rd party deps specifically for this module -->
|
||||||
<dependency>
|
|
||||||
<groupId>io.javalin</groupId>
|
|
||||||
<artifactId>javalin</artifactId>
|
|
||||||
<version>5.1.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.konghq</groupId>
|
<groupId>com.konghq</groupId>
|
||||||
<artifactId>unirest-java</artifactId>
|
<artifactId>unirest-java</artifactId>
|
||||||
|
@ -51,22 +51,6 @@ import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessUtils;
|
|||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiAssociationMetaData;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiAssociationMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Components;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Contact;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Content;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Example;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithListValue;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithSingleValue;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Info;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Method;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.OpenAPI;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Parameter;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Path;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.RequestBody;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Schema;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.SecurityScheme;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Tag;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||||
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
||||||
@ -93,6 +77,22 @@ import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.YamlUtils;
|
import com.kingsrook.qqq.backend.core.utils.YamlUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Components;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Contact;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Content;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Example;
|
||||||
|
import com.kingsrook.qqq.openapi.model.ExampleWithListValue;
|
||||||
|
import com.kingsrook.qqq.openapi.model.ExampleWithSingleValue;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Info;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Method;
|
||||||
|
import com.kingsrook.qqq.openapi.model.OpenAPI;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Parameter;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Path;
|
||||||
|
import com.kingsrook.qqq.openapi.model.RequestBody;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Response;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Schema;
|
||||||
|
import com.kingsrook.qqq.openapi.model.SecurityScheme;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Tag;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.ContentType;
|
||||||
import io.javalin.http.HttpStatus;
|
import io.javalin.http.HttpStatus;
|
||||||
import org.apache.commons.lang.BooleanUtils;
|
import org.apache.commons.lang.BooleanUtils;
|
||||||
|
@ -31,14 +31,14 @@ import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessInput;
|
|||||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessInputFieldsContainer;
|
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessInputFieldsContainer;
|
||||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaData;
|
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithListValue;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithSingleValue;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.HttpMethod;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormatPossibleValueEnum;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
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.fields.QFieldType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||||
|
import com.kingsrook.qqq.openapi.model.ExampleWithListValue;
|
||||||
|
import com.kingsrook.qqq.openapi.model.ExampleWithSingleValue;
|
||||||
|
import com.kingsrook.qqq.openapi.model.HttpMethod;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -27,15 +27,15 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.api.model.actions.HttpApiResponse;
|
import com.kingsrook.qqq.api.model.actions.HttpApiResponse;
|
||||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessOutputInterface;
|
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessOutputInterface;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Content;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Schema;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.StorageAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.StorageAction;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.storage.StorageInput;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Content;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Response;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Schema;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@ import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessMetaDataContaine
|
|||||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessUtils;
|
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessUtils;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.HttpMethod;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
@ -87,6 +86,7 @@ import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinAccessLogger;
|
import com.kingsrook.qqq.backend.javalin.QJavalinAccessLogger;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
||||||
|
import com.kingsrook.qqq.openapi.model.HttpMethod;
|
||||||
import io.javalin.apibuilder.ApiBuilder;
|
import io.javalin.apibuilder.ApiBuilder;
|
||||||
import io.javalin.apibuilder.EndpointGroup;
|
import io.javalin.apibuilder.EndpointGroup;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.ContentType;
|
||||||
@ -135,8 +135,17 @@ public class QJavalinApiHandler
|
|||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
// static endpoints to support rapidoc pages //
|
// static endpoints to support rapidoc pages //
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
ApiBuilder.get("/api/docs/js/rapidoc.min.js", (context) -> QJavalinApiHandler.serveResource(context, "rapidoc/rapidoc-9.3.4.min.js", MapBuilder.of("Content-Type", ContentType.JAVASCRIPT)));
|
try
|
||||||
ApiBuilder.get("/api/docs/css/qqq-api-styles.css", (context) -> QJavalinApiHandler.serveResource(context, "rapidoc/rapidoc-overrides.css", MapBuilder.of("Content-Type", ContentType.CSS)));
|
{
|
||||||
|
ApiBuilder.get("/api/docs/js/rapidoc.min.js", (context) -> QJavalinApiHandler.serveResource(context, "rapidoc/rapidoc-9.3.8.min.js", MapBuilder.of("Content-Type", ContentType.JAVASCRIPT)));
|
||||||
|
ApiBuilder.get("/api/docs/css/qqq-api-styles.css", (context) -> QJavalinApiHandler.serveResource(context, "rapidoc/rapidoc-overrides.css", MapBuilder.of("Content-Type", ContentType.CSS)));
|
||||||
|
}
|
||||||
|
catch(IllegalArgumentException iae)
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// assume a different module already registered these paths //
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
}
|
||||||
|
|
||||||
ApiBuilder.get("/apis.json", QJavalinApiHandler::doGetApisJson);
|
ApiBuilder.get("/apis.json", QJavalinApiHandler::doGetApisJson);
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
package com.kingsrook.qqq.api.model.actions;
|
package com.kingsrook.qqq.api.model.actions;
|
||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.OpenAPI;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
|
||||||
|
import com.kingsrook.qqq.openapi.model.OpenAPI;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -32,13 +32,13 @@ import java.util.Set;
|
|||||||
import com.kingsrook.qqq.api.model.APIVersion;
|
import com.kingsrook.qqq.api.model.APIVersion;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.SecurityScheme;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Server;
|
|
||||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
import com.kingsrook.qqq.openapi.model.SecurityScheme;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Server;
|
||||||
import org.apache.commons.lang.BooleanUtils;
|
import org.apache.commons.lang.BooleanUtils;
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,10 +23,10 @@ package com.kingsrook.qqq.api.model.metadata.fields;
|
|||||||
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Example;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Example;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -29,7 +29,6 @@ import com.kingsrook.qqq.api.ApiSupplementType;
|
|||||||
import com.kingsrook.qqq.api.model.APIVersionRange;
|
import com.kingsrook.qqq.api.model.APIVersionRange;
|
||||||
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
|
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.HttpMethod;
|
|
||||||
import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher;
|
import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher;
|
||||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
@ -39,6 +38,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
|
||||||
|
import com.kingsrook.qqq.openapi.model.HttpMethod;
|
||||||
import org.apache.commons.lang.BooleanUtils;
|
import org.apache.commons.lang.BooleanUtils;
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,11 +31,6 @@ import java.util.Objects;
|
|||||||
import com.kingsrook.qqq.api.actions.GenerateOpenApiSpecAction;
|
import com.kingsrook.qqq.api.actions.GenerateOpenApiSpecAction;
|
||||||
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
|
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.fields.ApiFieldMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Content;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithListValue;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithSingleValue;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Schema;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
@ -43,6 +38,11 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.ObjectUtils;
|
import com.kingsrook.qqq.backend.core.utils.ObjectUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Content;
|
||||||
|
import com.kingsrook.qqq.openapi.model.ExampleWithListValue;
|
||||||
|
import com.kingsrook.qqq.openapi.model.ExampleWithSingleValue;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Response;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Schema;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.ContentType;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
|
||||||
|
@ -25,11 +25,11 @@ package com.kingsrook.qqq.api.model.metadata.processes;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.api.model.actions.HttpApiResponse;
|
import com.kingsrook.qqq.api.model.actions.HttpApiResponse;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Response;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,9 +28,6 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Content;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
|
||||||
import com.kingsrook.qqq.api.model.openapi.Schema;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.ProcessSummaryFilterLink;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.ProcessSummaryFilterLink;
|
||||||
@ -42,6 +39,9 @@ import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.ListBuilder;
|
||||||
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Content;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Response;
|
||||||
|
import com.kingsrook.qqq.openapi.model.Schema;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.ContentType;
|
||||||
import org.apache.commons.lang.NotImplementedException;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
@ -38,7 +38,6 @@ import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessObjectOutput;
|
|||||||
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessSummaryListOutput;
|
import com.kingsrook.qqq.api.model.metadata.processes.ApiProcessSummaryListOutput;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaDataContainer;
|
||||||
import com.kingsrook.qqq.api.model.openapi.HttpMethod;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.customizers.AbstractPreDeleteCustomizer;
|
import com.kingsrook.qqq.backend.core.actions.customizers.AbstractPreDeleteCustomizer;
|
||||||
import com.kingsrook.qqq.backend.core.actions.customizers.AbstractPreInsertCustomizer;
|
import com.kingsrook.qqq.backend.core.actions.customizers.AbstractPreInsertCustomizer;
|
||||||
import com.kingsrook.qqq.backend.core.actions.customizers.AbstractPreUpdateCustomizer;
|
import com.kingsrook.qqq.backend.core.actions.customizers.AbstractPreUpdateCustomizer;
|
||||||
@ -86,6 +85,7 @@ import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwith
|
|||||||
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.StreamedETLWithFrontendProcess;
|
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.StreamedETLWithFrontendProcess;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RenderSavedReportMetaDataProducer;
|
import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RenderSavedReportMetaDataProducer;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
import com.kingsrook.qqq.openapi.model.HttpMethod;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -78,9 +78,10 @@ class QJavalinApiHandlerPermissionsTest extends BaseTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
qJavalinImplementation = new QJavalinImplementation(qInstance);
|
qJavalinImplementation = new QJavalinImplementation(qInstance);
|
||||||
qJavalinImplementation.startJavalinServer(PORT);
|
qJavalinImplementation.clearJavalinRoutes();
|
||||||
EndpointGroup routes = new QJavalinApiHandler(qInstance).getRoutes();
|
EndpointGroup routes = new QJavalinApiHandler(qInstance).getRoutes();
|
||||||
qJavalinImplementation.getJavalinService().routes(routes);
|
qJavalinImplementation.addJavalinRoutes(routes);
|
||||||
|
qJavalinImplementation.startJavalinServer(PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,9 +112,10 @@ class QJavalinApiHandlerTest extends BaseTest
|
|||||||
.withInitialVersion(TestUtils.V2022_Q4))));
|
.withInitialVersion(TestUtils.V2022_Q4))));
|
||||||
|
|
||||||
qJavalinImplementation = new QJavalinImplementation(qInstance);
|
qJavalinImplementation = new QJavalinImplementation(qInstance);
|
||||||
qJavalinImplementation.startJavalinServer(PORT);
|
qJavalinImplementation.clearJavalinRoutes();
|
||||||
EndpointGroup routes = new QJavalinApiHandler(qInstance).getRoutes();
|
EndpointGroup routes = new QJavalinApiHandler(qInstance).getRoutes();
|
||||||
qJavalinImplementation.getJavalinService().routes(routes);
|
qJavalinImplementation.addJavalinRoutes(routes);
|
||||||
|
qJavalinImplementation.startJavalinServer(PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user