mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-22 15:08:45 +00:00
Compare commits
5 Commits
snapshot-f
...
snapshot-f
Author | SHA1 | Date | |
---|---|---|---|
21f08f3499 | |||
8f334c9a53 | |||
9d64c34d8b | |||
a52fd34e7d | |||
6225169527 |
@ -1,51 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
############################################################################
|
if [ -z "$CIRCLE_BRANCH" ] && [ -z "$CIRCLE_TAG" ]; then
|
||||||
## adjust-pom.version.sh
|
echo "Error: env vars CIRCLE_BRANCH and CIRCLE_TAG were not set."
|
||||||
## During CircleCI builds - edit the qqq parent pom.xml, to set the
|
exit 1;
|
||||||
## <revision> value such that:
|
fi
|
||||||
## - feature-branch builds, tagged as snapshot-*, deploy with a version
|
|
||||||
## number that includes that tag's name (minus the snapshot- part)
|
|
||||||
## - integration-branch builds deploy with a version number that includes
|
|
||||||
## the branch name slugified
|
|
||||||
## - we never deploy -SNAPSHOT versions any more - because we don't believe
|
|
||||||
## it is ever valid to not know exactly what versions you are getting
|
|
||||||
## (perhaps because we are too loose with our versioning?)
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
POM=$(dirname $0)/../pom.xml
|
if [ "$CIRCLE_BRANCH" == "dev" ] || [ "$CIRCLE_BRANCH" == "staging" ] || [ "$CIRCLE_BRANCH" == "main" ] || [ \! -z $(echo "$CIRCLE_TAG" | grep "^version-") ]; then
|
||||||
echo "On branch: $CIRCLE_BRANCH, tag: $CIRCLE_TAG..."
|
echo "On a primary branch or tag [${CIRCLE_BRANCH}${CIRCLE_TAG}] - will not edit the pom version.";
|
||||||
|
echo "(or do we need to do this for dev...?)"
|
||||||
######################################################################
|
echo "(maybe we do this if the current version is a SNAPSHOT?)"
|
||||||
## ## only do anything if the committed pom has a -SNAPSHOT version ##
|
|
||||||
######################################################################
|
|
||||||
REVISION=$(grep '<revision>' $POM | sed 's/.*<revision>//;s/<.*//');
|
|
||||||
echo "<revision> in pom.xml is: $REVISION"
|
|
||||||
if [ \! $(echo "$REVISION" | grep SNAPSHOT) ]; then
|
|
||||||
echo "Not on a SNAPSHOT revision, so nothing to do here."
|
|
||||||
exit 0;
|
exit 0;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##################################################################################
|
if [ -n "$CIRCLE_BRANCH" ]; then
|
||||||
## ## figure out if we need a SLUG: a snapshot- tag, or an integration/ branch ##
|
SLUG=$(echo $CIRCLE_BRANCH | sed 's/[^a-zA-Z0-9]/-/g')
|
||||||
##################################################################################
|
else
|
||||||
SLUG=""
|
SLUG=$(echo $CIRCLE_TAG | sed 's/^snapshot-//g')
|
||||||
if [ $(echo "$CIRCLE_TAG" | grep ^snapshot-) ]; then
|
|
||||||
SLUG=$(echo "$CIRCLE_TAG" | sed "s/^snapshot-//")-
|
|
||||||
echo "Using slug [$SLUG] from tag [$CIRCLE_TAG]"
|
|
||||||
|
|
||||||
elif [ $(echo "$CIRCLE_BRANCH" | grep ^integration/) ]; then
|
|
||||||
SLUG=$(echo "$CIRCLE_BRANCH" | sed "s,/,-,g")-
|
|
||||||
echo "Using slug [$SLUG] from branch [$CIRCLE_BRANCH]"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
################################################################
|
POM=$(dirname $0)/../pom.xml
|
||||||
## ## build the replcaement for -SNAPSHOT, and update the pom ##
|
UNIQ=$(date +%Y%m%d-%H%M%S)-$(git rev-parse --short HEAD)
|
||||||
################################################################
|
SLUG="${SLUG}-${UNIQ}"
|
||||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
||||||
REPLACEMENT=${SLUG}${TIMESTAMP}
|
|
||||||
|
|
||||||
echo "Updating $POM -SNAPSHOT to: -$REPLACEMENT"
|
echo "Updating $POM <revision> to: $SLUG"
|
||||||
sed -i "s/-SNAPSHOT<\/revision>/-$REPLACEMENT<\/revision>/" $POM
|
sed -i "s/<revision>.*/<revision>$SLUG<\/revision>/" $POM
|
||||||
git diff $POM
|
git diff $POM
|
||||||
|
|
||||||
|
@ -79,19 +79,6 @@ 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
|
||||||
@ -143,7 +130,6 @@ 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
|
||||||
@ -151,7 +137,6 @@ 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:
|
||||||
|
@ -48,3 +48,5 @@ GNU Affero General Public License for more details.
|
|||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
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/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,9 @@ If the {link-table} has a `POST_QUERY_CUSTOMIZER` defined, then after records ar
|
|||||||
* `table` - *String, Required* - Name of the table being queried against.
|
* `table` - *String, Required* - Name of the table being queried against.
|
||||||
* `filter` - *<<QQueryFilter>> object* - Specification for what records should be returned, based on *<<QFilterCriteria>>* objects, and how they should be sorted, based on *<<QFilterOrderBy>>* objects.
|
* `filter` - *<<QQueryFilter>> object* - Specification for what records should be returned, based on *<<QFilterCriteria>>* objects, and how they should be sorted, based on *<<QFilterOrderBy>>* objects.
|
||||||
If a `filter` is not given, then all rows in the table will be returned by the query.
|
If a `filter` is not given, then all rows in the table will be returned by the query.
|
||||||
|
* `skip` - *Integer* - Optional number of records to be skipped at the beginning of the result set.
|
||||||
|
e.g., for implementing pagination.
|
||||||
|
* `limit` - *Integer* - Optional maximum number of records to be returned by the query.
|
||||||
* `transaction` - *QBackendTransaction object* - Optional transaction object.
|
* `transaction` - *QBackendTransaction object* - Optional transaction object.
|
||||||
** Behavior for this object is backend-dependant.
|
** Behavior for this object is backend-dependant.
|
||||||
In an RDBMS backend, this object is generally needed if you want your query to see data that may have been modified within the same transaction.
|
In an RDBMS backend, this object is generally needed if you want your query to see data that may have been modified within the same transaction.
|
||||||
@ -52,14 +55,6 @@ But if running a query to provide data as part of a process, then this can gener
|
|||||||
* `shouldMaskPassword` - *boolean, default: true* - Controls whether or not fields with `type` = `PASSWORD` should be masked, or if their actual values should be returned.
|
* `shouldMaskPassword` - *boolean, default: true* - Controls whether or not fields with `type` = `PASSWORD` should be masked, or if their actual values should be returned.
|
||||||
* `queryJoins` - *List of <<QueryJoin>> objects* - Optional list of tables to be joined with the main table being queried.
|
* `queryJoins` - *List of <<QueryJoin>> objects* - Optional list of tables to be joined with the main table being queried.
|
||||||
See QueryJoin below for further details.
|
See QueryJoin below for further details.
|
||||||
* `fieldNamesToInclude` - *Set of String* - Optional set of field names to be included in the records.
|
|
||||||
** Fields from a queryJoin must be prefixed by the join table's name or alias, and a period.
|
|
||||||
Field names from the table being queried should not have any sort of prefix.
|
|
||||||
** A `null` set here (default) means to include all fields from the table and any queryJoins set as select=true.
|
|
||||||
** An empty set will cause an error, as well any unrecognized field names.
|
|
||||||
** `QueryAction` will validate the set of field names, and throw an exception if any unrecognized names are given.
|
|
||||||
** _Note that this is an optional feature, which some backend modules may not implement.
|
|
||||||
Meaning, they would always return all fields._
|
|
||||||
|
|
||||||
==== QQueryFilter
|
==== QQueryFilter
|
||||||
A key component of *<<QueryInput>>*, a *QQueryFilter* defines both what records should be included in a query's results (e.g., an SQL `WHERE`), as well as how those results should be sorted (SQL `ORDER BY`).
|
A key component of *<<QueryInput>>*, a *QQueryFilter* defines both what records should be included in a query's results (e.g., an SQL `WHERE`), as well as how those results should be sorted (SQL `ORDER BY`).
|
||||||
@ -73,9 +68,6 @@ In general, multiple *orderBys* can be given (depending on backend implementatio
|
|||||||
** Each *subFilter* can include its own additional *subFilters*.
|
** Each *subFilter* can include its own additional *subFilters*.
|
||||||
** Each *subFilter* can specify a different *booleanOperator*.
|
** Each *subFilter* can specify a different *booleanOperator*.
|
||||||
** For example, consider the following *QQueryFilter*, that uses two *subFilters*, and a mix of *booleanOperators*
|
** For example, consider the following *QQueryFilter*, that uses two *subFilters*, and a mix of *booleanOperators*
|
||||||
* `skip` - *Integer* - Optional number of records to be skipped at the beginning of the result set.
|
|
||||||
e.g., for implementing pagination.
|
|
||||||
* `limit` - *Integer* - Optional maximum number of records to be returned by the query.
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
@ -38,13 +38,6 @@ See {link-permissionRules} for details.
|
|||||||
*** 1) by a single call to `.withStepList(List<QStepMetaData>)`, which internally adds each step into the `steps` map.
|
*** 1) by a single call to `.withStepList(List<QStepMetaData>)`, which internally adds each step into the `steps` map.
|
||||||
*** 2) by multiple calls to `.addStep(QStepMetaData)`, which adds a step to both the `stepList` and `steps` map.
|
*** 2) by multiple calls to `.addStep(QStepMetaData)`, which adds a step to both the `stepList` and `steps` map.
|
||||||
** If a process also needs optional steps (for a <<_custom_process_flow>>), they should be added by a call to `.addOptionalStep(QStepMetaData)`, which only places them in the `steps` map.
|
** If a process also needs optional steps (for a <<_custom_process_flow>>), they should be added by a call to `.addOptionalStep(QStepMetaData)`, which only places them in the `steps` map.
|
||||||
* `stepFlow` - *enum, default LINEAR* - specifies the the flow-control logic between steps. Possible values are:
|
|
||||||
** `LINEAR` - steps are executed in-order, through the `stepList`.
|
|
||||||
A backend step _can_ customize the `nextStepName` or re-order the `stepList`, if needed.
|
|
||||||
In a frontend step, a user may be given the option to go _back_ to a previous step as well.
|
|
||||||
** `STATE_MACHINE` - steps are executed as a Fine State Machine, starting with the first step in `stepList`,
|
|
||||||
but then proceeding based on the `nextStepName` specified by the previous step.
|
|
||||||
Thus allowing much more flexible flows.
|
|
||||||
* `schedule` - *<<QScheduleMetaData>>* - set up the process to run automatically on the specified schedule.
|
* `schedule` - *<<QScheduleMetaData>>* - set up the process to run automatically on the specified schedule.
|
||||||
See below for details.
|
See below for details.
|
||||||
* `minInputRecords` - *Integer* - #not used...#
|
* `minInputRecords` - *Integer* - #not used...#
|
||||||
@ -74,11 +67,6 @@ For processes with a user-interface, they must define one or more "screens" in t
|
|||||||
* `formFields` - *List of String* - list of field names used by the screen as form-inputs.
|
* `formFields` - *List of String* - list of field names used by the screen as form-inputs.
|
||||||
* `viewFields` - *List of String* - list of field names used by the screen as visible outputs.
|
* `viewFields` - *List of String* - list of field names used by the screen as visible outputs.
|
||||||
* `recordListFields` - *List of String* - list of field names used by the screen in a record listing.
|
* `recordListFields` - *List of String* - list of field names used by the screen in a record listing.
|
||||||
* `format` - *Optional String* - directive for a frontend to use specialized formatting for the display of the process.
|
|
||||||
** Consult frontend documentation for supported values and their meanings.
|
|
||||||
* `backStepName` - *Optional String* - For processes using `LINEAR` flow, if this value is given,
|
|
||||||
then the frontend should offer a control that the user can take (e.g., a button) to move back to an
|
|
||||||
earlier step in the process.
|
|
||||||
|
|
||||||
==== QFrontendComponentMetaData
|
==== QFrontendComponentMetaData
|
||||||
|
|
||||||
@ -102,13 +90,10 @@ Expects a process value named `html`.
|
|||||||
Expects process values named `downloadFileName` and `serverFilePath`.
|
Expects process values named `downloadFileName` and `serverFilePath`.
|
||||||
** `GOOGLE_DRIVE_SELECT_FOLDER` - Special form that presents a UI from Google Drive, where the user can select a folder (e.g., as a target for uploading files in a subsequent backend step).
|
** `GOOGLE_DRIVE_SELECT_FOLDER` - Special form that presents a UI from Google Drive, where the user can select a folder (e.g., as a target for uploading files in a subsequent backend step).
|
||||||
** `BULK_EDIT_FORM` - For use by the standard QQQ Bulk Edit process.
|
** `BULK_EDIT_FORM` - For use by the standard QQQ Bulk Edit process.
|
||||||
** `BULK_LOAD_FILE_MAPPING_FORM`, `BULK_LOAD_VALUE_MAPPING_FORM`, or `BULK_LOAD_PROFILE_FORM` - For use by the standard QQQ Bulk Load process.
|
|
||||||
** `VALIDATION_REVIEW_SCREEN` - For use by the QQQ Streamed ETL With Frontend process family of processes.
|
** `VALIDATION_REVIEW_SCREEN` - For use by the QQQ Streamed ETL With Frontend process family of processes.
|
||||||
Displays a component prompting the user to run full validation or to skip it, or, if full validation has been ran, then showing the results of that validation.
|
Displays a component prompting the user to run full validation or to skip it, or, if full validation has been ran, then showing the results of that validation.
|
||||||
** `PROCESS_SUMMARY_RESULTS` - For use by the QQQ Streamed ETL With Frontend process family of processes.
|
** `PROCESS_SUMMARY_RESULTS` - For use by the QQQ Streamed ETL With Frontend process family of processes.
|
||||||
Displays the summary results of running the process.
|
Displays the summary results of running the process.
|
||||||
** `WIDGET` - Render a QQQ Widget.
|
|
||||||
Requires that `widgetName` be given as a value for the component.
|
|
||||||
** `RECORD_LIST` - _Deprecated.
|
** `RECORD_LIST` - _Deprecated.
|
||||||
Showed a grid with a list of records as populated by the process._
|
Showed a grid with a list of records as populated by the process._
|
||||||
* `values` - *Map of String → Serializable* - Key=value pairs, with different expectations based on the component's `type`.
|
* `values` - *Map of String → Serializable* - Key=value pairs, with different expectations based on the component's `type`.
|
||||||
@ -131,27 +116,6 @@ It can be used, however, for example, to cause a `defaultValue` to be applied to
|
|||||||
It can also be used to cause the process to throw an error, if a field is marked as `isRequired`, but a value is not present.
|
It can also be used to cause the process to throw an error, if a field is marked as `isRequired`, but a value is not present.
|
||||||
** `recordListMetaData` - *RecordListMetaData object* - _Not used at this time._
|
** `recordListMetaData` - *RecordListMetaData object* - _Not used at this time._
|
||||||
|
|
||||||
==== QStateMachineStep
|
|
||||||
|
|
||||||
Processes that use `flow = STATE_MACHINE` should use process steps of type `QStateMachineStep`.
|
|
||||||
|
|
||||||
A common pattern seen in state-machine processes, is that they will present a frontend-step to a user,
|
|
||||||
then always run a given backend-step in response to that screen which the user submitted.
|
|
||||||
Inside that backend-step, custom application logic will determine the next state to go to,
|
|
||||||
which is typically another frontend-step (which would then submit data to its corresponding backend-step,
|
|
||||||
and continue the FSM).
|
|
||||||
|
|
||||||
To help facilitate this pattern, factory methods exist on `QStateMachineStep`,
|
|
||||||
for constructing the commonly-expected types of state-machine steps:
|
|
||||||
|
|
||||||
* `frontendThenBackend(name, frontendStep, backendStep)` - for the frontend-then-backend pattern described above.
|
|
||||||
* `backendOnly(name, backendStep)` - for a state that only has a backend step.
|
|
||||||
This might be useful as a “reset” step, to run before restarting a state-loop.
|
|
||||||
* `frontendOnly(name, frontendStep)` - for a state that only has a frontend step,
|
|
||||||
which would always be followed by another state, which must be specified as the `defaultNextStepName`
|
|
||||||
on the `QStateMachineStep`.
|
|
||||||
|
|
||||||
|
|
||||||
==== BasepullConfiguration
|
==== BasepullConfiguration
|
||||||
|
|
||||||
A "Basepull" process is a common pattern where an application needs to perform some action on all new (or updated) records from a particular data source.
|
A "Basepull" process is a common pattern where an application needs to perform some action on all new (or updated) records from a particular data source.
|
||||||
@ -254,10 +218,12 @@ But for some cases, doing page-level transactions can reduce long-transactions a
|
|||||||
* `withSchedule(QScheduleMetaData schedule)` - Add a <<QScheduleMetaData>> to the process.
|
* `withSchedule(QScheduleMetaData schedule)` - Add a <<QScheduleMetaData>> to the process.
|
||||||
|
|
||||||
[#_custom_process_flow]
|
[#_custom_process_flow]
|
||||||
==== How to customize a Linear process flow
|
==== Custom Process Flow
|
||||||
As referenced in the definition of the <<_QProcessMetaData_Properties,QProcessMetaData Properties>>, by default,
|
As referenced in the definition of the <<_QProcessMetaData_Properties,QProcessMetaData Properties>>, by default, a process
|
||||||
(with `flow = LINEAR`) a process will execute each of its steps in-order, as defined in the `stepList` property.
|
will execute each of its steps in-order, as defined in the `stepList` property.
|
||||||
However, a Backend Step can customize this flow as follows:
|
However, a Backend Step can customize this flow #todo - write more clearly here...
|
||||||
|
|
||||||
|
There are generally 2 method to call (in a `BackendStep`) to do a dynamic flow:
|
||||||
|
|
||||||
* `RunBackendStepOutput.setOverrideLastStepName(String stepName)`
|
* `RunBackendStepOutput.setOverrideLastStepName(String stepName)`
|
||||||
** QQQ's `RunProcessAction` keeps track of which step it "last" ran, e.g., to tell it which one to run next.
|
** QQQ's `RunProcessAction` keeps track of which step it "last" ran, e.g., to tell it which one to run next.
|
||||||
@ -273,7 +239,7 @@ does need to be found in the new `stepNameList` - otherwise, the framework will
|
|||||||
for figuring out where to go next.
|
for figuring out where to go next.
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
.Example of a defining process that can use a customized linear flow:
|
.Example of a defining process that can use a flexible flow:
|
||||||
----
|
----
|
||||||
// for a case like this, it would be recommended to define all step names in constants:
|
// for a case like this, it would be recommended to define all step names in constants:
|
||||||
public final static String STEP_START = "start";
|
public final static String STEP_START = "start";
|
||||||
@ -358,21 +324,4 @@ public static class StartStep implements BackendStep
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
[#_process_back]
|
|
||||||
==== How to allow a process to go back
|
|
||||||
|
|
||||||
The simplest option to allow a process to present a "Back" button to users,
|
|
||||||
thus allowing them to move backward through a process
|
|
||||||
(e.g., from a review screen back to an earlier input screen), is to set the property `backStepName`
|
|
||||||
on a `QFrontendStepMetaData`.
|
|
||||||
|
|
||||||
If the step that is executed after the user hits "Back" is a backend step, then within that
|
|
||||||
step, `runBackendStepInput.getIsStepBack()` will return `true` (but ONLY within that first step after
|
|
||||||
the user hits "Back"). It may be necessary within individual processes to be aware that the user
|
|
||||||
has chosen to go back, to reset certain values in the process's state.
|
|
||||||
|
|
||||||
Alternatively, if a frontend step's "Back" behavior needs to be dynamic (e.g., sometimes not available,
|
|
||||||
or sometimes targeting different steps in the process), then in a backend step that runs before the
|
|
||||||
frontend step, a call to `runBackendStepOutput.getProcessState().setBackStepName()` can be made,
|
|
||||||
to customize the value which would otherwise come from the `QFrontendStepMetaData`.
|
|
||||||
|
|
||||||
|
3
pom.xml
3
pom.xml
@ -36,7 +36,6 @@
|
|||||||
<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>
|
||||||
@ -47,7 +46,7 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>0.24.0-SNAPSHOT</revision>
|
<revision>0.21.0-SNAPSHOT</revision>
|
||||||
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
@ -102,11 +102,6 @@
|
|||||||
<artifactId>fastexcel</artifactId>
|
<artifactId>fastexcel</artifactId>
|
||||||
<version>0.12.15</version>
|
<version>0.12.15</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.dhatim</groupId>
|
|
||||||
<artifactId>fastexcel-reader</artifactId>
|
|
||||||
<version>0.18.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.poi</groupId>
|
<groupId>org.apache.poi</groupId>
|
||||||
<artifactId>poi</artifactId>
|
<artifactId>poi</artifactId>
|
||||||
@ -117,14 +112,6 @@
|
|||||||
<artifactId>poi-ooxml</artifactId>
|
<artifactId>poi-ooxml</artifactId>
|
||||||
<version>5.2.5</version>
|
<version>5.2.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- adding to help FastExcel -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>2.16.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.auth0</groupId>
|
<groupId>com.auth0</groupId>
|
||||||
<artifactId>auth0</artifactId>
|
<artifactId>auth0</artifactId>
|
||||||
|
@ -225,13 +225,7 @@ public class AuditAction extends AbstractQActionFunction<AuditInput, AuditOutput
|
|||||||
{
|
{
|
||||||
if(auditSingleInput.getSecurityKeyValues() == null || !auditSingleInput.getSecurityKeyValues().containsKey(recordSecurityLock.getSecurityKeyType()))
|
if(auditSingleInput.getSecurityKeyValues() == null || !auditSingleInput.getSecurityKeyValues().containsKey(recordSecurityLock.getSecurityKeyType()))
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////////////
|
throw (new QException("Missing securityKeyValue [" + recordSecurityLock.getSecurityKeyType() + "] in audit request for table " + auditSingleInput.getAuditTableName()));
|
||||||
// originally, this case threw... //
|
|
||||||
// but i think it's better to record the audit, just //
|
|
||||||
// missing its security key value, then to fail... //
|
|
||||||
///////////////////////////////////////////////////////
|
|
||||||
// throw (new QException("Missing securityKeyValue [" + recordSecurityLock.getSecurityKeyType() + "] in audit request for table " + auditSingleInput.getAuditTableName()));
|
|
||||||
LOG.info("Missing securityKeyValue in audit request", logPair("table", auditSingleInput.getAuditTableName()), logPair("securityKey", recordSecurityLock.getSecurityKeyType()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +272,7 @@ public class AuditAction extends AbstractQActionFunction<AuditInput, AuditOutput
|
|||||||
List<QRecord> auditDetailRecords = new ArrayList<>();
|
List<QRecord> auditDetailRecords = new ArrayList<>();
|
||||||
for(AuditSingleInput auditSingleInput : CollectionUtils.nonNullList(input.getAuditSingleInputList()))
|
for(AuditSingleInput auditSingleInput : CollectionUtils.nonNullList(input.getAuditSingleInputList()))
|
||||||
{
|
{
|
||||||
Long auditId = insertOutput.getRecords().get(i++).getValueLong("id");
|
Integer auditId = insertOutput.getRecords().get(i++).getValueInteger("id");
|
||||||
if(auditId == null)
|
if(auditId == null)
|
||||||
{
|
{
|
||||||
LOG.warn("Missing an id for inserted audit - so won't be able to store its child details...");
|
LOG.warn("Missing an id for inserted audit - so won't be able to store its child details...");
|
||||||
|
@ -24,12 +24,10 @@ package com.kingsrook.qqq.backend.core.actions.customizers;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.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.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
@ -145,19 +143,4 @@ public interface RecordCustomizerUtilityInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
default Map<Serializable, QRecord> getOldRecordMap(List<QRecord> oldRecordList, UpdateInput updateInput)
|
|
||||||
{
|
|
||||||
Map<Serializable, QRecord> oldRecordMap = new HashMap<>();
|
|
||||||
for(QRecord qRecord : oldRecordList)
|
|
||||||
{
|
|
||||||
oldRecordMap.put(qRecord.getValue(updateInput.getTable().getPrimaryKeyField()), qRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (oldRecordMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -301,9 +301,6 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
widgetData.setAllowRecordEdit(BooleanUtils.isTrue(ValueUtils.getValueAsBoolean(input.getQueryParams().get("allowRecordEdit"))));
|
|
||||||
widgetData.setAllowRecordDelete(BooleanUtils.isTrue(ValueUtils.getValueAsBoolean(input.getQueryParams().get("allowRecordDelete"))));
|
|
||||||
|
|
||||||
return (new RenderWidgetOutput(widgetData));
|
return (new RenderWidgetOutput(widgetData));
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
|
@ -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;
|
||||||
@ -40,9 +40,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
|||||||
** - alertType - name of entry in AlertType enum (ERROR, WARNING, SUCCESS)
|
** - alertType - name of entry in AlertType enum (ERROR, WARNING, SUCCESS)
|
||||||
** - alertHtml - html to display inside the alert (other than its icon)
|
** - alertHtml - html to display inside the alert (other than its icon)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class AlertWidgetRenderer extends AbstractWidgetRenderer implements MetaDataProducerInterface<QWidgetMetaData>
|
public class ProcessAlertWidget extends AbstractWidgetRenderer implements MetaDataProducerInterface<QWidgetMetaData>
|
||||||
{
|
{
|
||||||
public static final String NAME = "AlertWidgetRenderer";
|
public static final String NAME = "ProcessAlertWidget";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,18 +28,13 @@ 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;
|
||||||
@ -54,7 +49,6 @@ 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;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -63,12 +57,6 @@ import com.kingsrook.qqq.backend.core.utils.memoization.Memoization;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class MetaDataAction
|
public class MetaDataAction
|
||||||
{
|
{
|
||||||
private static final QLogger LOG = QLogger.getLogger(MetaDataAction.class);
|
|
||||||
|
|
||||||
private static Memoization<QInstance, MetaDataFilterInterface> metaDataFilterMemoization = new Memoization<>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -76,10 +64,10 @@ public class MetaDataAction
|
|||||||
{
|
{
|
||||||
ActionHelper.validateSession(metaDataInput);
|
ActionHelper.validateSession(metaDataInput);
|
||||||
|
|
||||||
MetaDataOutput metaDataOutput = new MetaDataOutput();
|
// todo pre-customization - just get to modify the request?
|
||||||
Map<String, AppTreeNode> treeNodes = new LinkedHashMap<>();
|
MetaDataOutput metaDataOutput = new MetaDataOutput();
|
||||||
|
|
||||||
MetaDataFilterInterface filter = getMetaDataFilter();
|
Map<String, AppTreeNode> treeNodes = new LinkedHashMap<>();
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
// map tables to frontend metadata //
|
// map tables to frontend metadata //
|
||||||
@ -90,11 +78,6 @@ 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))
|
||||||
{
|
{
|
||||||
@ -119,11 +102,6 @@ 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))
|
||||||
{
|
{
|
||||||
@ -144,11 +122,6 @@ 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))
|
||||||
{
|
{
|
||||||
@ -169,11 +142,6 @@ 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))
|
||||||
{
|
{
|
||||||
@ -206,19 +174,9 @@ public class MetaDataAction
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!filter.allowApp(metaDataInput, app))
|
apps.put(appName, new QFrontendAppMetaData(app, metaDataOutput));
|
||||||
{
|
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())
|
||||||
@ -232,42 +190,9 @@ 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);
|
||||||
|
|
||||||
@ -303,33 +228,6 @@ 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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,7 +40,6 @@ 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;
|
||||||
@ -258,20 +257,11 @@ public class RunBackendStepAction
|
|||||||
{
|
{
|
||||||
runBackendStepOutput.seedFromRequest(runBackendStepInput);
|
runBackendStepOutput.seedFromRequest(runBackendStepInput);
|
||||||
|
|
||||||
Object codeObject;
|
Class<?> codeClass = Class.forName(code.getName());
|
||||||
if(code instanceof QCodeReferenceLambda<?> qCodeReferenceLambda)
|
Object codeObject = codeClass.getConstructor().newInstance();
|
||||||
{
|
|
||||||
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 codeReference [" + code + "] is not a reference to a BackendStep"));
|
throw (new QException("The supplied code [" + codeClass.getName() + "] is not an instance of BackendStep"));
|
||||||
}
|
}
|
||||||
|
|
||||||
backendStepCodeObject.run(runBackendStepInput, runBackendStepOutput);
|
backendStepCodeObject.run(runBackendStepInput, runBackendStepOutput);
|
||||||
|
@ -28,7 +28,6 @@ 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;
|
||||||
@ -59,7 +58,6 @@ 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;
|
||||||
@ -81,7 +79,6 @@ public class RunProcessAction
|
|||||||
{
|
{
|
||||||
private static final QLogger LOG = QLogger.getLogger(RunProcessAction.class);
|
private static final QLogger LOG = QLogger.getLogger(RunProcessAction.class);
|
||||||
|
|
||||||
public static final String BASEPULL_KEY_VALUE = "basepullKeyValue";
|
|
||||||
public static final String BASEPULL_THIS_RUNTIME_KEY = "basepullThisRuntimeKey";
|
public static final String BASEPULL_THIS_RUNTIME_KEY = "basepullThisRuntimeKey";
|
||||||
public static final String BASEPULL_LAST_RUNTIME_KEY = "basepullLastRuntimeKey";
|
public static final String BASEPULL_LAST_RUNTIME_KEY = "basepullLastRuntimeKey";
|
||||||
public static final String BASEPULL_TIMESTAMP_FIELD = "basepullTimestampField";
|
public static final String BASEPULL_TIMESTAMP_FIELD = "basepullTimestampField";
|
||||||
@ -122,12 +119,6 @@ public class RunProcessAction
|
|||||||
UUIDAndTypeStateKey stateKey = new UUIDAndTypeStateKey(UUID.fromString(runProcessInput.getProcessUUID()), StateType.PROCESS_STATUS);
|
UUIDAndTypeStateKey stateKey = new UUIDAndTypeStateKey(UUID.fromString(runProcessInput.getProcessUUID()), StateType.PROCESS_STATUS);
|
||||||
ProcessState processState = primeProcessState(runProcessInput, stateKey, process);
|
ProcessState processState = primeProcessState(runProcessInput, stateKey, process);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// these should always be clear when we're starting a run - so make sure they haven't leaked from previous //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
processState.clearNextStepName();
|
|
||||||
processState.clearBackStepName();
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// if process is 'basepull' style, keep track of 'now' //
|
// if process is 'basepull' style, keep track of 'now' //
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
@ -142,11 +133,90 @@ public class RunProcessAction
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch(Objects.requireNonNull(process.getStepFlow(), "Process [" + process.getName() + "] has a null stepFlow."))
|
String lastStepName = runProcessInput.getStartAfterStep();
|
||||||
|
|
||||||
|
STEP_LOOP:
|
||||||
|
while(true)
|
||||||
{
|
{
|
||||||
case LINEAR -> runLinearStepLoop(process, processState, stateKey, runProcessInput, runProcessOutput);
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
case STATE_MACHINE -> runStateMachineStep(runProcessInput.getStartAfterStep(), process, processState, stateKey, runProcessInput, runProcessOutput, 0);
|
// always refresh the step list - as any step that runs can modify it (in the process state). //
|
||||||
default -> throw (new QException("Unhandled process step flow: " + process.getStepFlow()));
|
// 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)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// 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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -188,310 +258,6 @@ public class RunProcessAction
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private void runLinearStepLoop(QProcessMetaData process, ProcessState processState, UUIDAndTypeStateKey stateKey, RunProcessInput runProcessInput, RunProcessOutput runProcessOutput) throws Exception
|
|
||||||
{
|
|
||||||
String lastStepName = runProcessInput.getStartAfterStep();
|
|
||||||
String startAtStep = runProcessInput.getStartAtStep();
|
|
||||||
|
|
||||||
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. //
|
|
||||||
// deal with if we were told, from the input, to start After a step, or start At a step. //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
List<QStepMetaData> stepList;
|
|
||||||
if(startAtStep == null)
|
|
||||||
{
|
|
||||||
stepList = getAvailableStepList(processState, process, lastStepName, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stepList = getAvailableStepList(processState, process, startAtStep, true);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// clear this field - so after we run a step, we'll then loop in last-step mode. //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
startAtStep = null;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// if we're going to run a backend step now, let it see that this is a step-back //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
processState.setIsStepBack(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// only let this value be set for the original back step - don't let it stick around. //
|
|
||||||
// if a process wants to keep track of this itself, it can, but in a different slot. //
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
processState.setIsStepBack(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// in case we broke from the loop above (e.g., by going directly into a frontend step), once again make sure to lower this flag. //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
processState.setIsStepBack(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
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());
|
|
||||||
|
|
||||||
if(StringUtils.hasContent(step.getBackStepName()) && processState.getBackStepName().isEmpty())
|
|
||||||
{
|
|
||||||
processState.setBackStepName(step.getBackStepName());
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
processState.clearBackStepName();
|
|
||||||
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();
|
|
||||||
processState.clearBackStepName();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -569,12 +335,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 processMetaDataAdjustment - //
|
// if we're restoring an old state, we can discard a previously stored updatedFrontendStepList - //
|
||||||
// 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().setProcessMetaDataAdjustment(null);
|
optionalProcessState.get().setUpdatedFrontendStepList(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 //
|
||||||
@ -589,40 +355,16 @@ 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.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
RunBackendStepOutput runBackendStep(RunProcessInput runProcessInput, QProcessMetaData process, RunProcessOutput runProcessOutput, UUIDAndTypeStateKey stateKey, QBackendStepMetaData backendStep, QProcessMetaData qProcessMetaData, ProcessState processState) throws Exception
|
protected 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());
|
||||||
@ -667,10 +409,8 @@ public class RunProcessAction
|
|||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Get the list of steps which are eligible to run.
|
** Get the list of steps which are eligible to run.
|
||||||
**
|
|
||||||
** lastStep will be included in the list, or not, based on includeLastStep.
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
static List<QStepMetaData> getAvailableStepList(ProcessState processState, QProcessMetaData process, String lastStep, boolean includeLastStep) throws QException
|
private List<QStepMetaData> getAvailableStepList(ProcessState processState, QProcessMetaData process, String lastStep) throws QException
|
||||||
{
|
{
|
||||||
if(lastStep == null)
|
if(lastStep == null)
|
||||||
{
|
{
|
||||||
@ -697,10 +437,6 @@ public class RunProcessAction
|
|||||||
if(stepName.equals(lastStep))
|
if(stepName.equals(lastStep))
|
||||||
{
|
{
|
||||||
foundLastStep = true;
|
foundLastStep = true;
|
||||||
if(includeLastStep)
|
|
||||||
{
|
|
||||||
validStepNames.add(stepName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (stepNamesToSteps(process, validStepNames));
|
return (stepNamesToSteps(process, validStepNames));
|
||||||
@ -712,7 +448,7 @@ public class RunProcessAction
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static List<QStepMetaData> stepNamesToSteps(QProcessMetaData process, List<String> stepNames) throws QException
|
private List<QStepMetaData> stepNamesToSteps(QProcessMetaData process, List<String> stepNames) throws QException
|
||||||
{
|
{
|
||||||
List<QStepMetaData> result = new ArrayList<>();
|
List<QStepMetaData> result = new ArrayList<>();
|
||||||
|
|
||||||
@ -781,13 +517,9 @@ public class RunProcessAction
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected String determineBasepullKeyValue(QProcessMetaData process, RunProcessInput runProcessInput, BasepullConfiguration basepullConfiguration) throws QException
|
protected String determineBasepullKeyValue(QProcessMetaData process, BasepullConfiguration basepullConfiguration) throws QException
|
||||||
{
|
{
|
||||||
String basepullKeyValue = (basepullConfiguration.getKeyValue() != null) ? basepullConfiguration.getKeyValue() : process.getName();
|
String basepullKeyValue = (basepullConfiguration.getKeyValue() != null) ? basepullConfiguration.getKeyValue() : process.getName();
|
||||||
if(runProcessInput.getValueString(BASEPULL_KEY_VALUE) != null)
|
|
||||||
{
|
|
||||||
basepullKeyValue = runProcessInput.getValueString(BASEPULL_KEY_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// if process specifies that it uses variants, look for that data in the session and append to our basepull key //
|
// if process specifies that it uses variants, look for that data in the session and append to our basepull key //
|
||||||
@ -819,7 +551,7 @@ public class RunProcessAction
|
|||||||
String basepullTableName = basepullConfiguration.getTableName();
|
String basepullTableName = basepullConfiguration.getTableName();
|
||||||
String basepullKeyFieldName = basepullConfiguration.getKeyField();
|
String basepullKeyFieldName = basepullConfiguration.getKeyField();
|
||||||
String basepullLastRunTimeFieldName = basepullConfiguration.getLastRunTimeFieldName();
|
String basepullLastRunTimeFieldName = basepullConfiguration.getLastRunTimeFieldName();
|
||||||
String basepullKeyValue = determineBasepullKeyValue(process, runProcessInput, basepullConfiguration);
|
String basepullKeyValue = determineBasepullKeyValue(process, basepullConfiguration);
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// get the stored basepull timestamp //
|
// get the stored basepull timestamp //
|
||||||
@ -899,7 +631,7 @@ public class RunProcessAction
|
|||||||
String basepullKeyFieldName = basepullConfiguration.getKeyField();
|
String basepullKeyFieldName = basepullConfiguration.getKeyField();
|
||||||
String basepullLastRunTimeFieldName = basepullConfiguration.getLastRunTimeFieldName();
|
String basepullLastRunTimeFieldName = basepullConfiguration.getLastRunTimeFieldName();
|
||||||
Integer basepullHoursBackForInitialTimestamp = basepullConfiguration.getHoursBackForInitialTimestamp();
|
Integer basepullHoursBackForInitialTimestamp = basepullConfiguration.getHoursBackForInitialTimestamp();
|
||||||
String basepullKeyValue = determineBasepullKeyValue(process, runProcessInput, basepullConfiguration);
|
String basepullKeyValue = determineBasepullKeyValue(process, basepullConfiguration);
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// get the stored basepull timestamp //
|
// get the stored basepull timestamp //
|
||||||
|
@ -42,7 +42,6 @@ import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.async.AsyncRecordPipeLoop;
|
import com.kingsrook.qqq.backend.core.actions.async.AsyncRecordPipeLoop;
|
||||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.DataSourceQueryInputCustomizer;
|
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.DataSourceQueryInputCustomizer;
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportCustomRecordSourceInterface;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportViewCustomizer;
|
import com.kingsrook.qqq.backend.core.actions.reporting.customizers.ReportViewCustomizer;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||||
@ -63,8 +62,6 @@ import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportOutput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.QueryHint;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.QueryHint;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.CriteriaMissingInputValueBehavior;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.FilterUseCase;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.JoinsContext;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.JoinsContext;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||||
@ -305,19 +302,10 @@ public class GenerateReportAction extends AbstractQActionFunction<ReportInput, R
|
|||||||
JoinsContext joinsContext = null;
|
JoinsContext joinsContext = null;
|
||||||
if(dataSource != null)
|
if(dataSource != null)
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// count records, if applicable, from the data source - for populating into the //
|
|
||||||
// countByDataSource map, as well as for checking if too many rows (e.g., for excel) //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
countDataSourceRecords(reportInput, dataSource, reportFormat);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// if there's a source table, set up a joins context, to use below for looking up fields //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
if(StringUtils.hasContent(dataSource.getSourceTable()))
|
if(StringUtils.hasContent(dataSource.getSourceTable()))
|
||||||
{
|
{
|
||||||
QQueryFilter queryFilter = dataSource.getQueryFilter() == null ? new QQueryFilter() : dataSource.getQueryFilter().clone();
|
joinsContext = new JoinsContext(QContext.getQInstance(), dataSource.getSourceTable(), cloneDataSourceQueryJoins(dataSource), dataSource.getQueryFilter() == null ? null : dataSource.getQueryFilter().clone());
|
||||||
joinsContext = new JoinsContext(QContext.getQInstance(), dataSource.getSourceTable(), dataSource.getQueryJoins(), queryFilter);
|
countDataSourceRecords(reportInput, dataSource, reportFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +329,6 @@ public class GenerateReportAction extends AbstractQActionFunction<ReportInput, R
|
|||||||
field.setName(column.getName());
|
field.setName(column.getName());
|
||||||
if(StringUtils.hasContent(column.getLabel()))
|
if(StringUtils.hasContent(column.getLabel()))
|
||||||
{
|
{
|
||||||
|
|
||||||
field.setLabel(column.getLabel());
|
field.setLabel(column.getLabel());
|
||||||
}
|
}
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
@ -359,33 +346,23 @@ public class GenerateReportAction extends AbstractQActionFunction<ReportInput, R
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private void countDataSourceRecords(ReportInput reportInput, QReportDataSource dataSource, ReportFormat reportFormat) throws QException
|
private void countDataSourceRecords(ReportInput reportInput, QReportDataSource dataSource, ReportFormat reportFormat) throws QException
|
||||||
{
|
{
|
||||||
Integer count = null;
|
QQueryFilter queryFilter = dataSource.getQueryFilter() == null ? new QQueryFilter() : dataSource.getQueryFilter().clone();
|
||||||
if(dataSource.getCustomRecordSource() != null)
|
setInputValuesInQueryFilter(reportInput, queryFilter);
|
||||||
|
|
||||||
|
CountInput countInput = new CountInput();
|
||||||
|
countInput.setTableName(dataSource.getSourceTable());
|
||||||
|
countInput.setFilter(queryFilter);
|
||||||
|
countInput.setQueryJoins(cloneDataSourceQueryJoins(dataSource));
|
||||||
|
CountOutput countOutput = new CountAction().execute(countInput);
|
||||||
|
|
||||||
|
if(countOutput.getCount() != null)
|
||||||
{
|
{
|
||||||
// todo - add `count` method to interface?
|
countByDataSource.put(dataSource.getName(), countOutput.getCount());
|
||||||
}
|
|
||||||
else if(StringUtils.hasContent(dataSource.getSourceTable()))
|
|
||||||
{
|
|
||||||
QQueryFilter queryFilter = dataSource.getQueryFilter() == null ? new QQueryFilter() : dataSource.getQueryFilter().clone();
|
|
||||||
setInputValuesInQueryFilter(reportInput, queryFilter);
|
|
||||||
|
|
||||||
CountInput countInput = new CountInput();
|
if(reportFormat.getMaxRows() != null && countOutput.getCount() > reportFormat.getMaxRows())
|
||||||
countInput.setTableName(dataSource.getSourceTable());
|
|
||||||
countInput.setFilter(queryFilter);
|
|
||||||
countInput.setQueryJoins(cloneDataSourceQueryJoins(dataSource));
|
|
||||||
CountOutput countOutput = new CountAction().execute(countInput);
|
|
||||||
|
|
||||||
count = countOutput.getCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(count != null)
|
|
||||||
{
|
|
||||||
countByDataSource.put(dataSource.getName(), count);
|
|
||||||
|
|
||||||
if(reportFormat.getMaxRows() != null && count > reportFormat.getMaxRows())
|
|
||||||
{
|
{
|
||||||
throw (new QUserFacingException("The requested report would include more rows ("
|
throw (new QUserFacingException("The requested report would include more rows ("
|
||||||
+ String.format("%,d", count) + ") than the maximum allowed ("
|
+ String.format("%,d", countOutput.getCount()) + ") than the maximum allowed ("
|
||||||
+ String.format("%,d", reportFormat.getMaxRows()) + ") for the selected file format (" + reportFormat + ")."));
|
+ String.format("%,d", reportFormat.getMaxRows()) + ") for the selected file format (" + reportFormat + ")."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -446,19 +423,13 @@ public class GenerateReportAction extends AbstractQActionFunction<ReportInput, R
|
|||||||
String tableLabel = ObjectUtils.tryElse(() -> QContext.getQInstance().getTable(dataSource.getSourceTable()).getLabel(), Objects.requireNonNullElse(dataSource.getSourceTable(), ""));
|
String tableLabel = ObjectUtils.tryElse(() -> QContext.getQInstance().getTable(dataSource.getSourceTable()).getLabel(), Objects.requireNonNullElse(dataSource.getSourceTable(), ""));
|
||||||
AtomicInteger consumedCount = new AtomicInteger(0);
|
AtomicInteger consumedCount = new AtomicInteger(0);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// run a record pipe loop, over the query (or other data-supplier/source) for this data source //
|
// run a record pipe loop, over the query for this data source //
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
RecordPipe recordPipe = new BufferedRecordPipe(1000);
|
RecordPipe recordPipe = new BufferedRecordPipe(1000);
|
||||||
new AsyncRecordPipeLoop().run("Report[" + reportInput.getReportName() + "]", null, recordPipe, (callback) ->
|
new AsyncRecordPipeLoop().run("Report[" + reportInput.getReportName() + "]", null, recordPipe, (callback) ->
|
||||||
{
|
{
|
||||||
if(dataSource.getCustomRecordSource() != null)
|
if(dataSource.getSourceTable() != null)
|
||||||
{
|
|
||||||
ReportCustomRecordSourceInterface recordSource = QCodeLoader.getAdHoc(ReportCustomRecordSourceInterface.class, dataSource.getCustomRecordSource());
|
|
||||||
recordSource.execute(reportInput, dataSource, recordPipe);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
else if(dataSource.getSourceTable() != null)
|
|
||||||
{
|
{
|
||||||
QQueryFilter queryFilter = dataSource.getQueryFilter() == null ? new QQueryFilter() : dataSource.getQueryFilter().clone();
|
QQueryFilter queryFilter = dataSource.getQueryFilter() == null ? new QQueryFilter() : dataSource.getQueryFilter().clone();
|
||||||
setInputValuesInQueryFilter(reportInput, queryFilter);
|
setInputValuesInQueryFilter(reportInput, queryFilter);
|
||||||
@ -616,56 +587,7 @@ public class GenerateReportAction extends AbstractQActionFunction<ReportInput, R
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
queryFilter.interpretValues(reportInput.getInputValues());
|
||||||
// for reports defined in meta-data, the established rule is, that missing input variable values are discarded. //
|
|
||||||
// but for non-meta-data reports (e.g., user-saved), we expect an exception for missing values. //
|
|
||||||
// so, set those use-cases up. //
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
FilterUseCase filterUseCase;
|
|
||||||
if(StringUtils.hasContent(reportInput.getReportName()) && QContext.getQInstance().getReport(reportInput.getReportName()) != null)
|
|
||||||
{
|
|
||||||
filterUseCase = new ReportFromMetaDataFilterUseCase();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filterUseCase = new ReportNotFromMetaDataFilterUseCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
queryFilter.interpretValues(reportInput.getInputValues(), filterUseCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private static class ReportFromMetaDataFilterUseCase implements FilterUseCase
|
|
||||||
{
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
@Override
|
|
||||||
public CriteriaMissingInputValueBehavior getDefaultCriteriaMissingInputValueBehavior()
|
|
||||||
{
|
|
||||||
return CriteriaMissingInputValueBehavior.REMOVE_FROM_FILTER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private static class ReportNotFromMetaDataFilterUseCase implements FilterUseCase
|
|
||||||
{
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
@Override
|
|
||||||
public CriteriaMissingInputValueBehavior getDefaultCriteriaMissingInputValueBehavior()
|
|
||||||
{
|
|
||||||
return CriteriaMissingInputValueBehavior.THROW_EXCEPTION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.customizers;
|
|
||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.reporting.RecordPipe;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportInput;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportDataSource;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Interface to be implemented to do a custom source of data for a report
|
|
||||||
** (instead of just a query against a table).
|
|
||||||
*******************************************************************************/
|
|
||||||
public interface ReportCustomRecordSourceInterface
|
|
||||||
{
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
** Given the report input, put records into the pipe, for the report.
|
|
||||||
***************************************************************************/
|
|
||||||
void execute(ReportInput reportInput, QReportDataSource reportDataSource, RecordPipe recordPipe) throws QException;
|
|
||||||
|
|
||||||
}
|
|
@ -124,11 +124,10 @@ public class ExcelPoiBasedStreamingExportStreamer implements ExportStreamerInter
|
|||||||
private Writer activeSheetWriter = null;
|
private Writer activeSheetWriter = null;
|
||||||
private StreamedSheetWriter sheetWriter = null;
|
private StreamedSheetWriter sheetWriter = null;
|
||||||
|
|
||||||
private QReportView currentView = null;
|
private QReportView currentView = null;
|
||||||
private Map<String, List<QFieldMetaData>> fieldsPerView = new HashMap<>();
|
private Map<String, List<QFieldMetaData>> fieldsPerView = new HashMap<>();
|
||||||
private Map<String, Integer> rowsPerView = new HashMap<>();
|
private Map<String, Integer> rowsPerView = new HashMap<>();
|
||||||
private Map<String, String> labelViewsByName = new HashMap<>();
|
private Map<String, String> labelViewsByName = new HashMap<>();
|
||||||
private Map<String, String> sheetReferenceByViewName = new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -181,7 +180,6 @@ public class ExcelPoiBasedStreamingExportStreamer implements ExportStreamerInter
|
|||||||
String sheetReference = sheet.getPackagePart().getPartName().getName().substring(1);
|
String sheetReference = sheet.getPackagePart().getPartName().getName().substring(1);
|
||||||
sheetMapByExcelReference.put(sheetReference, sheet);
|
sheetMapByExcelReference.put(sheetReference, sheet);
|
||||||
sheetMapByViewName.put(view.getName(), sheet);
|
sheetMapByViewName.put(view.getName(), sheet);
|
||||||
sheetReferenceByViewName.put(view.getName(), sheetReference);
|
|
||||||
sheetCounter++;
|
sheetCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +446,7 @@ public class ExcelPoiBasedStreamingExportStreamer implements ExportStreamerInter
|
|||||||
// - with a new output stream writer //
|
// - with a new output stream writer //
|
||||||
// - and with a SpreadsheetWriter //
|
// - and with a SpreadsheetWriter //
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
zipOutputStream.putNextEntry(new ZipEntry(sheetReferenceByViewName.get(view.getName())));
|
zipOutputStream.putNextEntry(new ZipEntry("xl/worksheets/sheet" + this.sheetIndex++ + ".xml"));
|
||||||
activeSheetWriter = new OutputStreamWriter(zipOutputStream);
|
activeSheetWriter = new OutputStreamWriter(zipOutputStream);
|
||||||
sheetWriter = new StreamedSheetWriter(activeSheetWriter);
|
sheetWriter = new StreamedSheetWriter(activeSheetWriter);
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ public class DeleteAction
|
|||||||
QTableMetaData table = deleteInput.getTable();
|
QTableMetaData table = deleteInput.getTable();
|
||||||
List<QRecord> primaryKeysNotFound = validateRecordsExistAndCanBeAccessed(deleteInput, oldRecordList.get());
|
List<QRecord> primaryKeysNotFound = validateRecordsExistAndCanBeAccessed(deleteInput, oldRecordList.get());
|
||||||
|
|
||||||
ValidateRecordSecurityLockHelper.validateSecurityFields(table, oldRecordList.get(), ValidateRecordSecurityLockHelper.Action.DELETE, deleteInput.getTransaction());
|
ValidateRecordSecurityLockHelper.validateSecurityFields(table, oldRecordList.get(), ValidateRecordSecurityLockHelper.Action.DELETE);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// after all validations, run the pre-delete customizer, if there is one //
|
// after all validations, run the pre-delete customizer, if there is one //
|
||||||
|
@ -258,7 +258,7 @@ public class InsertAction extends AbstractQActionFunction<InsertInput, InsertOut
|
|||||||
}
|
}
|
||||||
|
|
||||||
runPreInsertCustomizerIfItIsTime(insertInput, isPreview, preInsertCustomizer, AbstractPreInsertCustomizer.WhenToRun.BEFORE_SECURITY_CHECKS);
|
runPreInsertCustomizerIfItIsTime(insertInput, isPreview, preInsertCustomizer, AbstractPreInsertCustomizer.WhenToRun.BEFORE_SECURITY_CHECKS);
|
||||||
ValidateRecordSecurityLockHelper.validateSecurityFields(insertInput.getTable(), insertInput.getRecords(), ValidateRecordSecurityLockHelper.Action.INSERT, insertInput.getTransaction());
|
ValidateRecordSecurityLockHelper.validateSecurityFields(insertInput.getTable(), insertInput.getRecords(), ValidateRecordSecurityLockHelper.Action.INSERT);
|
||||||
|
|
||||||
runPreInsertCustomizerIfItIsTime(insertInput, isPreview, preInsertCustomizer, AbstractPreInsertCustomizer.WhenToRun.AFTER_ALL_VALIDATIONS);
|
runPreInsertCustomizerIfItIsTime(insertInput, isPreview, preInsertCustomizer, AbstractPreInsertCustomizer.WhenToRun.AFTER_ALL_VALIDATIONS);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import java.io.Serializable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -51,10 +50,8 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperat
|
|||||||
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.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.QueryJoin;
|
|
||||||
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.data.QRecordEntity;
|
|
||||||
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.fields.AdornmentType;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
@ -67,7 +64,6 @@ import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleDispatcher;
|
|||||||
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ListingHash;
|
import com.kingsrook.qqq.backend.core.utils.ListingHash;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -105,8 +101,6 @@ public class QueryAction
|
|||||||
throw (new QException("A table named [" + queryInput.getTableName() + "] was not found in the active QInstance"));
|
throw (new QException("A table named [" + queryInput.getTableName() + "] was not found in the active QInstance"));
|
||||||
}
|
}
|
||||||
|
|
||||||
validateFieldNamesToInclude(queryInput);
|
|
||||||
|
|
||||||
QBackendMetaData backend = queryInput.getBackend();
|
QBackendMetaData backend = queryInput.getBackend();
|
||||||
postQueryRecordCustomizer = QCodeLoader.getTableCustomizer(table, TableCustomizers.POST_QUERY_RECORD.getRole());
|
postQueryRecordCustomizer = QCodeLoader.getTableCustomizer(table, TableCustomizers.POST_QUERY_RECORD.getRole());
|
||||||
this.queryInput = queryInput;
|
this.queryInput = queryInput;
|
||||||
@ -164,125 +158,6 @@ public class QueryAction
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
** if QueryInput contains a set of FieldNamesToInclude, then validate that
|
|
||||||
** those are known field names in the table being queried, or a selected
|
|
||||||
** queryJoin.
|
|
||||||
***************************************************************************/
|
|
||||||
static void validateFieldNamesToInclude(QueryInput queryInput) throws QException
|
|
||||||
{
|
|
||||||
Set<String> fieldNamesToInclude = queryInput.getFieldNamesToInclude();
|
|
||||||
if(fieldNamesToInclude == null)
|
|
||||||
{
|
|
||||||
////////////////////////////////
|
|
||||||
// null set means select all. //
|
|
||||||
////////////////////////////////
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fieldNamesToInclude.isEmpty())
|
|
||||||
{
|
|
||||||
/////////////////////////////////////
|
|
||||||
// empty set, however, is an error //
|
|
||||||
/////////////////////////////////////
|
|
||||||
throw (new QException("An empty set of fieldNamesToInclude was given as queryInput, which is not allowed."));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> unrecognizedFieldNames = new ArrayList<>();
|
|
||||||
Map<String, QTableMetaData> selectedQueryJoins = null;
|
|
||||||
for(String fieldName : fieldNamesToInclude)
|
|
||||||
{
|
|
||||||
if(fieldName.contains("."))
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
// handle names with dots - fields from joins //
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
String[] parts = fieldName.split("\\.");
|
|
||||||
if(parts.length != 2)
|
|
||||||
{
|
|
||||||
unrecognizedFieldNames.add(fieldName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String tableOrAlias = parts[0];
|
|
||||||
String fieldNamePart = parts[1];
|
|
||||||
|
|
||||||
////////////////////////////////////////////
|
|
||||||
// build map of queryJoins being selected //
|
|
||||||
////////////////////////////////////////////
|
|
||||||
if(selectedQueryJoins == null)
|
|
||||||
{
|
|
||||||
selectedQueryJoins = new HashMap<>();
|
|
||||||
for(QueryJoin queryJoin : CollectionUtils.nonNullList(queryInput.getQueryJoins()))
|
|
||||||
{
|
|
||||||
if(queryJoin.getSelect())
|
|
||||||
{
|
|
||||||
String joinTableOrAlias = queryJoin.getJoinTableOrItsAlias();
|
|
||||||
QTableMetaData joinTable = QContext.getQInstance().getTable(queryJoin.getJoinTable());
|
|
||||||
if(joinTable != null)
|
|
||||||
{
|
|
||||||
selectedQueryJoins.put(joinTableOrAlias, joinTable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!selectedQueryJoins.containsKey(tableOrAlias))
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////
|
|
||||||
// unrecognized tableOrAlias is an error //
|
|
||||||
///////////////////////////////////////////
|
|
||||||
unrecognizedFieldNames.add(fieldName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QTableMetaData joinTable = selectedQueryJoins.get(tableOrAlias);
|
|
||||||
if(!joinTable.getFields().containsKey(fieldNamePart))
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////////////
|
|
||||||
// unrecognized field within the join table is an error //
|
|
||||||
//////////////////////////////////////////////////////////
|
|
||||||
unrecognizedFieldNames.add(fieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// non-join fields - just ensure field name is in table's fields map //
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
if(!queryInput.getTable().getFields().containsKey(fieldName))
|
|
||||||
{
|
|
||||||
unrecognizedFieldNames.add(fieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!unrecognizedFieldNames.isEmpty())
|
|
||||||
{
|
|
||||||
throw (new QException("QueryInput contained " + unrecognizedFieldNames.size() + " unrecognized field name" + StringUtils.plural(unrecognizedFieldNames) + ": " + StringUtils.join(",", unrecognizedFieldNames)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** shorthand way to call for the most common use-case, when you just want the
|
|
||||||
** entities to be returned, and you just want to pass in a table name and filter.
|
|
||||||
*******************************************************************************/
|
|
||||||
public static <T extends QRecordEntity> List<T> execute(String tableName, Class<T> entityClass, QQueryFilter filter) throws QException
|
|
||||||
{
|
|
||||||
QueryAction queryAction = new QueryAction();
|
|
||||||
QueryInput queryInput = new QueryInput();
|
|
||||||
queryInput.setTableName(tableName);
|
|
||||||
queryInput.setFilter(filter);
|
|
||||||
QueryOutput queryOutput = queryAction.execute(queryInput);
|
|
||||||
return (queryOutput.getRecordEntities(entityClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** shorthand way to call for the most common use-case, when you just want the
|
** shorthand way to call for the most common use-case, when you just want the
|
||||||
** records to be returned, and you just want to pass in a table name and filter.
|
** records to be returned, and you just want to pass in a table name and filter.
|
||||||
|
@ -261,7 +261,7 @@ public class UpdateAction
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ValidateRecordSecurityLockHelper.validateSecurityFields(table, updateInput.getRecords(), ValidateRecordSecurityLockHelper.Action.UPDATE, updateInput.getTransaction());
|
ValidateRecordSecurityLockHelper.validateSecurityFields(table, updateInput.getRecords(), ValidateRecordSecurityLockHelper.Action.UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(updateInput.getInputSource().shouldValidateRequiredFields())
|
if(updateInput.getInputSource().shouldValidateRequiredFields())
|
||||||
@ -374,7 +374,7 @@ public class UpdateAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateRecordSecurityLockHelper.validateSecurityFields(table, updateInput.getRecords(), ValidateRecordSecurityLockHelper.Action.UPDATE, updateInput.getTransaction());
|
ValidateRecordSecurityLockHelper.validateSecurityFields(table, updateInput.getRecords(), ValidateRecordSecurityLockHelper.Action.UPDATE);
|
||||||
|
|
||||||
for(QRecord record : page)
|
for(QRecord record : page)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,6 @@ import java.util.Collections;
|
|||||||
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.kingsrook.qqq.backend.core.actions.QBackendTransaction;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
@ -84,7 +83,7 @@ public class ValidateRecordSecurityLockHelper
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void validateSecurityFields(QTableMetaData table, List<QRecord> records, Action action, QBackendTransaction transaction) throws QException
|
public static void validateSecurityFields(QTableMetaData table, List<QRecord> records, Action action) throws QException
|
||||||
{
|
{
|
||||||
MultiRecordSecurityLock locksToCheck = getRecordSecurityLocks(table, action);
|
MultiRecordSecurityLock locksToCheck = getRecordSecurityLocks(table, action);
|
||||||
if(locksToCheck == null || CollectionUtils.nullSafeIsEmpty(locksToCheck.getLocks()))
|
if(locksToCheck == null || CollectionUtils.nullSafeIsEmpty(locksToCheck.getLocks()))
|
||||||
@ -102,7 +101,7 @@ public class ValidateRecordSecurityLockHelper
|
|||||||
// actually check lock values //
|
// actually check lock values //
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
Map<Serializable, RecordWithErrors> errorRecords = new HashMap<>();
|
Map<Serializable, RecordWithErrors> errorRecords = new HashMap<>();
|
||||||
evaluateRecordLocks(table, records, action, locksToCheck, errorRecords, new ArrayList<>(), madeUpPrimaryKeys, transaction);
|
evaluateRecordLocks(table, records, action, locksToCheck, errorRecords, new ArrayList<>(), madeUpPrimaryKeys);
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
// propagate errors to records //
|
// propagate errors to records //
|
||||||
@ -142,7 +141,7 @@ public class ValidateRecordSecurityLockHelper
|
|||||||
** BUT - WRITE locks - in their case, we read the record no matter what, and in
|
** BUT - WRITE locks - in their case, we read the record no matter what, and in
|
||||||
** here we need to verify we have a key that allows us to WRITE the record.
|
** here we need to verify we have a key that allows us to WRITE the record.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static void evaluateRecordLocks(QTableMetaData table, List<QRecord> records, Action action, RecordSecurityLock recordSecurityLock, Map<Serializable, RecordWithErrors> errorRecords, List<Integer> treePosition, Map<Serializable, QRecord> madeUpPrimaryKeys, QBackendTransaction transaction) throws QException
|
private static void evaluateRecordLocks(QTableMetaData table, List<QRecord> records, Action action, RecordSecurityLock recordSecurityLock, Map<Serializable, RecordWithErrors> errorRecords, List<Integer> treePosition, Map<Serializable, QRecord> madeUpPrimaryKeys) throws QException
|
||||||
{
|
{
|
||||||
if(recordSecurityLock instanceof MultiRecordSecurityLock multiRecordSecurityLock)
|
if(recordSecurityLock instanceof MultiRecordSecurityLock multiRecordSecurityLock)
|
||||||
{
|
{
|
||||||
@ -153,7 +152,7 @@ public class ValidateRecordSecurityLockHelper
|
|||||||
for(RecordSecurityLock childLock : CollectionUtils.nonNullList(multiRecordSecurityLock.getLocks()))
|
for(RecordSecurityLock childLock : CollectionUtils.nonNullList(multiRecordSecurityLock.getLocks()))
|
||||||
{
|
{
|
||||||
treePosition.add(i);
|
treePosition.add(i);
|
||||||
evaluateRecordLocks(table, records, action, childLock, errorRecords, treePosition, madeUpPrimaryKeys, transaction);
|
evaluateRecordLocks(table, records, action, childLock, errorRecords, treePosition, madeUpPrimaryKeys);
|
||||||
treePosition.remove(treePosition.size() - 1);
|
treePosition.remove(treePosition.size() - 1);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -226,7 +225,6 @@ public class ValidateRecordSecurityLockHelper
|
|||||||
// query will be like (fkey1=? and fkey2=?) OR (fkey1=? and fkey2=?) OR (fkey1=? and fkey2=?) //
|
// query will be like (fkey1=? and fkey2=?) OR (fkey1=? and fkey2=?) OR (fkey1=? and fkey2=?) //
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
QueryInput queryInput = new QueryInput();
|
QueryInput queryInput = new QueryInput();
|
||||||
queryInput.setTransaction(transaction);
|
|
||||||
queryInput.setTableName(leftMostJoin.getLeftTable());
|
queryInput.setTableName(leftMostJoin.getLeftTable());
|
||||||
QQueryFilter filter = new QQueryFilter().withBooleanOperator(QQueryFilter.BooleanOperator.OR);
|
QQueryFilter filter = new QQueryFilter().withBooleanOperator(QQueryFilter.BooleanOperator.OR);
|
||||||
queryInput.setFilter(filter);
|
queryInput.setFilter(filter);
|
||||||
|
@ -28,6 +28,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -467,8 +468,7 @@ public class QValueFormatter
|
|||||||
{
|
{
|
||||||
for(QFieldMetaData field : table.getFields().values())
|
for(QFieldMetaData field : table.getFields().values())
|
||||||
{
|
{
|
||||||
Optional<FieldAdornment> fileDownloadAdornment = field.getAdornment(AdornmentType.FILE_DOWNLOAD);
|
if(field.getType().equals(QFieldType.BLOB))
|
||||||
if(fileDownloadAdornment.isPresent())
|
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// file name comes from: //
|
// file name comes from: //
|
||||||
@ -478,7 +478,20 @@ public class QValueFormatter
|
|||||||
// - tableLabel primaryKey fieldLabel //
|
// - tableLabel primaryKey fieldLabel //
|
||||||
// - and - if the FILE_DOWNLOAD adornment had a DEFAULT_EXTENSION, then it gets added (preceded by a dot) //
|
// - and - if the FILE_DOWNLOAD adornment had a DEFAULT_EXTENSION, then it gets added (preceded by a dot) //
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
Map<String, Serializable> adornmentValues = fileDownloadAdornment.get().getValues();
|
Optional<FieldAdornment> fileDownloadAdornment = field.getAdornment(AdornmentType.FILE_DOWNLOAD);
|
||||||
|
Map<String, Serializable> adornmentValues = Collections.emptyMap();
|
||||||
|
|
||||||
|
if(fileDownloadAdornment.isPresent())
|
||||||
|
{
|
||||||
|
adornmentValues = fileDownloadAdornment.get().getValues();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// don't change blobs unless they are file-downloads //
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String fileNameField = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.FILE_NAME_FIELD));
|
String fileNameField = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.FILE_NAME_FIELD));
|
||||||
String fileNameFormat = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.FILE_NAME_FORMAT));
|
String fileNameFormat = ValueUtils.getValueAsString(adornmentValues.get(AdornmentType.FileDownloadValues.FILE_NAME_FORMAT));
|
||||||
@ -529,13 +542,7 @@ public class QValueFormatter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
record.setValue(field.getName(), "/data/" + table.getName() + "/" + primaryKey + "/" + field.getName() + "/" + fileName);
|
||||||
// if field type is blob, update its value //
|
|
||||||
/////////////////////////////////////////////
|
|
||||||
if(QFieldType.BLOB.equals(field.getType()))
|
|
||||||
{
|
|
||||||
record.setValue(field.getName(), "/data/" + table.getName() + "/" + primaryKey + "/" + field.getName() + "/" + fileName);
|
|
||||||
}
|
|
||||||
record.setDisplayValue(field.getName(), fileName);
|
record.setDisplayValue(field.getName(), fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,8 @@ import java.io.Serializable;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
@ -54,7 +50,7 @@ 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.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -65,9 +61,6 @@ public class SearchPossibleValueSourceAction
|
|||||||
{
|
{
|
||||||
private static final QLogger LOG = QLogger.getLogger(SearchPossibleValueSourceAction.class);
|
private static final QLogger LOG = QLogger.getLogger(SearchPossibleValueSourceAction.class);
|
||||||
|
|
||||||
private static final Set<String> warnedAboutUnexpectedValueField = Collections.synchronizedSet(new HashSet<>());
|
|
||||||
private static final Set<String> warnedAboutUnexpectedNoOfFieldsToSearchByLabel = Collections.synchronizedSet(new HashSet<>());
|
|
||||||
|
|
||||||
private QPossibleValueTranslator possibleValueTranslator;
|
private QPossibleValueTranslator possibleValueTranslator;
|
||||||
|
|
||||||
|
|
||||||
@ -117,7 +110,6 @@ public class SearchPossibleValueSourceAction
|
|||||||
List<Serializable> matchingIds = new ArrayList<>();
|
List<Serializable> matchingIds = new ArrayList<>();
|
||||||
|
|
||||||
List<?> inputIdsAsCorrectType = convertInputIdsToEnumIdType(possibleValueSource, input.getIdList());
|
List<?> inputIdsAsCorrectType = convertInputIdsToEnumIdType(possibleValueSource, input.getIdList());
|
||||||
Set<String> labels = null;
|
|
||||||
|
|
||||||
for(QPossibleValue<?> possibleValue : possibleValueSource.getEnumValues())
|
for(QPossibleValue<?> possibleValue : possibleValueSource.getEnumValues())
|
||||||
{
|
{
|
||||||
@ -130,24 +122,12 @@ public class SearchPossibleValueSourceAction
|
|||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(input.getLabelList() != null)
|
|
||||||
{
|
|
||||||
if(labels == null)
|
|
||||||
{
|
|
||||||
labels = input.getLabelList().stream().filter(Objects::nonNull).map(l -> l.toLowerCase()).collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(labels.contains(possibleValue.getLabel().toLowerCase()))
|
|
||||||
{
|
|
||||||
match = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(StringUtils.hasContent(input.getSearchTerm()))
|
if(StringUtils.hasContent(input.getSearchTerm()))
|
||||||
{
|
{
|
||||||
match = (Objects.equals(ValueUtils.getValueAsString(possibleValue.getId()).toLowerCase(), input.getSearchTerm().toLowerCase())
|
match = (Objects.equals(ValueUtils.getValueAsString(possibleValue.getId()).toLowerCase(), input.getSearchTerm().toLowerCase())
|
||||||
|| possibleValue.getLabel().toLowerCase().startsWith(input.getSearchTerm().toLowerCase()));
|
|| possibleValue.getLabel().toLowerCase().startsWith(input.getSearchTerm().toLowerCase()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -188,37 +168,21 @@ public class SearchPossibleValueSourceAction
|
|||||||
|
|
||||||
Object anIdFromTheEnum = possibleValueSource.getEnumValues().get(0).getId();
|
Object anIdFromTheEnum = possibleValueSource.getEnumValues().get(0).getId();
|
||||||
|
|
||||||
for(Serializable inputId : inputIdList)
|
if(anIdFromTheEnum instanceof Integer)
|
||||||
{
|
{
|
||||||
Object properlyTypedId = null;
|
inputIdList.forEach(id -> rs.add(ValueUtils.getValueAsInteger(id)));
|
||||||
try
|
}
|
||||||
{
|
else if(anIdFromTheEnum instanceof String)
|
||||||
if(anIdFromTheEnum instanceof Integer)
|
{
|
||||||
{
|
inputIdList.forEach(id -> rs.add(ValueUtils.getValueAsString(id)));
|
||||||
properlyTypedId = ValueUtils.getValueAsInteger(inputId);
|
}
|
||||||
}
|
else if(anIdFromTheEnum instanceof Boolean)
|
||||||
else if(anIdFromTheEnum instanceof String)
|
{
|
||||||
{
|
inputIdList.forEach(id -> rs.add(ValueUtils.getValueAsBoolean(id)));
|
||||||
properlyTypedId = ValueUtils.getValueAsString(inputId);
|
}
|
||||||
}
|
else
|
||||||
else if(anIdFromTheEnum instanceof Boolean)
|
{
|
||||||
{
|
LOG.warn("Unexpected type [" + anIdFromTheEnum.getClass().getSimpleName() + "] for ids in enum: " + possibleValueSource.getName());
|
||||||
properlyTypedId = ValueUtils.getValueAsBoolean(inputId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG.warn("Unexpected type [" + anIdFromTheEnum.getClass().getSimpleName() + "] for ids in enum: " + possibleValueSource.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
LOG.debug("Error converting possible value id to expected id type", e, logPair("value", inputId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (properlyTypedId != null)
|
|
||||||
{
|
|
||||||
rs.add(properlyTypedId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (rs);
|
return (rs);
|
||||||
@ -245,53 +209,6 @@ public class SearchPossibleValueSourceAction
|
|||||||
{
|
{
|
||||||
queryFilter.addCriteria(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.IN, input.getIdList()));
|
queryFilter.addCriteria(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.IN, input.getIdList()));
|
||||||
}
|
}
|
||||||
else if(input.getLabelList() != null)
|
|
||||||
{
|
|
||||||
List<String> fieldNames = new ArrayList<>();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// the 'value fields' will either be 'id' or 'label' (which means, use the fields from the tableMetaData's label fields) //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
for(String valueField : possibleValueSource.getValueFields())
|
|
||||||
{
|
|
||||||
if("id".equals(valueField))
|
|
||||||
{
|
|
||||||
fieldNames.add(table.getPrimaryKeyField());
|
|
||||||
}
|
|
||||||
else if("label".equals(valueField))
|
|
||||||
{
|
|
||||||
if(table.getRecordLabelFields() != null)
|
|
||||||
{
|
|
||||||
fieldNames.addAll(table.getRecordLabelFields());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String message = "Unexpected valueField defined in possibleValueSource when searching possibleValueSource by label (required: 'id' or 'label')";
|
|
||||||
if(!warnedAboutUnexpectedValueField.contains(possibleValueSource.getName()))
|
|
||||||
{
|
|
||||||
LOG.warn(message, logPair("valueField", valueField), logPair("possibleValueSource", possibleValueSource.getName()));
|
|
||||||
warnedAboutUnexpectedValueField.add(possibleValueSource.getName());
|
|
||||||
}
|
|
||||||
output.setWarning(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fieldNames.size() == 1)
|
|
||||||
{
|
|
||||||
queryFilter.addCriteria(new QFilterCriteria(fieldNames.get(0), QCriteriaOperator.IN, input.getLabelList()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String message = "Unexpected number of fields found for searching possibleValueSource by label (required: 1, found: " + fieldNames.size() + ")";
|
|
||||||
if(!warnedAboutUnexpectedNoOfFieldsToSearchByLabel.contains(possibleValueSource.getName()))
|
|
||||||
{
|
|
||||||
LOG.warn(message);
|
|
||||||
warnedAboutUnexpectedNoOfFieldsToSearchByLabel.add(possibleValueSource.getName());
|
|
||||||
}
|
|
||||||
output.setWarning(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String searchTerm = input.getSearchTerm();
|
String searchTerm = input.getSearchTerm();
|
||||||
@ -343,6 +260,9 @@ public class SearchPossibleValueSourceAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo - skip & limit as params
|
||||||
|
queryFilter.setLimit(250);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// if given a default filter, make it the 'top level' filter and the one we just created a subfilter //
|
// if given a default filter, make it the 'top level' filter and the one we just created a subfilter //
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -352,9 +272,6 @@ public class SearchPossibleValueSourceAction
|
|||||||
queryFilter = input.getDefaultQueryFilter();
|
queryFilter = input.getDefaultQueryFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
queryFilter.setLimit(input.getLimit());
|
|
||||||
queryFilter.setSkip(input.getSkip());
|
|
||||||
|
|
||||||
queryFilter.setOrderBys(possibleValueSource.getOrderByFields());
|
queryFilter.setOrderBys(possibleValueSource.getOrderByFields());
|
||||||
|
|
||||||
queryInput.setFilter(queryFilter);
|
queryInput.setFilter(queryFilter);
|
||||||
@ -371,7 +288,7 @@ public class SearchPossibleValueSourceAction
|
|||||||
fieldName = table.getPrimaryKeyField();
|
fieldName = table.getPrimaryKeyField();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Serializable> ids = queryOutput.getRecords().stream().map(r -> r.getValue(fieldName)).toList();
|
List<Serializable> ids = queryOutput.getRecords().stream().map(r -> r.getValue(fieldName)).toList();
|
||||||
List<QPossibleValue<?>> qPossibleValues = possibleValueTranslator.buildTranslatedPossibleValueList(possibleValueSource, ids);
|
List<QPossibleValue<?>> qPossibleValues = possibleValueTranslator.buildTranslatedPossibleValueList(possibleValueSource, ids);
|
||||||
output.setResults(qPossibleValues);
|
output.setResults(qPossibleValues);
|
||||||
|
|
||||||
@ -384,7 +301,7 @@ public class SearchPossibleValueSourceAction
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private SearchPossibleValueSourceOutput searchPossibleValueCustom(SearchPossibleValueSourceInput input, QPossibleValueSource possibleValueSource) throws QException
|
private SearchPossibleValueSourceOutput searchPossibleValueCustom(SearchPossibleValueSourceInput input, QPossibleValueSource possibleValueSource)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -397,10 +314,11 @@ public class SearchPossibleValueSourceAction
|
|||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
String message = "Error sending searching custom possible value source [" + input.getPossibleValueSourceName() + "]";
|
// LOG.warn("Error sending [" + value + "] for field [" + field + "] through custom code for PVS [" + field.getPossibleValueSourceName() + "]", e);
|
||||||
LOG.warn(message, e);
|
|
||||||
throw (new QException(message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new NotImplementedException("Not impleemnted");
|
||||||
|
// return (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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<>();
|
|
||||||
}
|
|
||||||
}
|
|
@ -42,7 +42,6 @@ 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.QWidgetMetaDataInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType.FileUploadAdornment;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.DynamicDefaultValueBehavior;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.DynamicDefaultValueBehavior;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
@ -55,12 +54,10 @@ import com.kingsrook.qqq.backend.core.model.metadata.permissions.MetaDataWithPer
|
|||||||
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.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.possiblevalues.QPossibleValueSourceType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QComponentType;
|
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;
|
||||||
@ -77,11 +74,6 @@ import com.kingsrook.qqq.backend.core.processes.implementations.bulk.edit.BulkEd
|
|||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.edit.BulkEditTransformStep;
|
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.edit.BulkEditTransformStep;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertExtractStep;
|
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertExtractStep;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertLoadStep;
|
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertLoadStep;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertPrepareFileMappingStep;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertPrepareFileUploadStep;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertPrepareValueMappingStep;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertReceiveFileMappingStep;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertReceiveValueMappingStep;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertTransformStep;
|
import com.kingsrook.qqq.backend.core.processes.implementations.bulk.insert.BulkInsertTransformStep;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.ExtractViaQueryStep;
|
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.ExtractViaQueryStep;
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.StreamedETLWithFrontendProcess;
|
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.StreamedETLWithFrontendProcess;
|
||||||
@ -418,27 +410,10 @@ 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()))
|
||||||
{
|
{
|
||||||
if(isSubStep && (step.getName().endsWith(".backend") || step.getName().endsWith(".frontend")))
|
step.setLabel(nameToLabel(step.getName()));
|
||||||
{
|
|
||||||
step.setLabel(nameToLabel(step.getName().replaceFirst("\\.(backend|frontend)", "")));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
step.setLabel(nameToLabel(step.getName()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
step.getInputFields().forEach(this::enrichField);
|
step.getInputFields().forEach(this::enrichField);
|
||||||
@ -459,13 +434,6 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -840,7 +808,7 @@ public class QInstanceEnricher
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void defineTableBulkInsert(QInstance qInstance, QTableMetaData table, String processName)
|
private void defineTableBulkInsert(QInstance qInstance, QTableMetaData table, String processName)
|
||||||
{
|
{
|
||||||
Map<String, Serializable> values = new HashMap<>();
|
Map<String, Serializable> values = new HashMap<>();
|
||||||
values.put(StreamedETLWithFrontendProcess.FIELD_DESTINATION_TABLE, table.getName());
|
values.put(StreamedETLWithFrontendProcess.FIELD_DESTINATION_TABLE, table.getName());
|
||||||
@ -852,7 +820,6 @@ public class QInstanceEnricher
|
|||||||
values
|
values
|
||||||
)
|
)
|
||||||
.withName(processName)
|
.withName(processName)
|
||||||
.withIcon(new QIcon().withName("library_add"))
|
|
||||||
.withLabel(table.getLabel() + " Bulk Insert")
|
.withLabel(table.getLabel() + " Bulk Insert")
|
||||||
.withTableName(table.getName())
|
.withTableName(table.getName())
|
||||||
.withIsHidden(true)
|
.withIsHidden(true)
|
||||||
@ -883,74 +850,18 @@ public class QInstanceEnricher
|
|||||||
.map(QFieldMetaData::getLabel)
|
.map(QFieldMetaData::getLabel)
|
||||||
.collect(Collectors.joining(", "));
|
.collect(Collectors.joining(", "));
|
||||||
|
|
||||||
QBackendStepMetaData prepareFileUploadStep = new QBackendStepMetaData()
|
|
||||||
.withName("prepareFileUpload")
|
|
||||||
.withCode(new QCodeReference(BulkInsertPrepareFileUploadStep.class));
|
|
||||||
|
|
||||||
QFrontendStepMetaData uploadScreen = new QFrontendStepMetaData()
|
QFrontendStepMetaData uploadScreen = new QFrontendStepMetaData()
|
||||||
.withName("upload")
|
.withName("upload")
|
||||||
.withLabel("Upload File")
|
.withLabel("Upload File")
|
||||||
.withFormField(new QFieldMetaData("theFile", QFieldType.BLOB)
|
.withFormField(new QFieldMetaData("theFile", QFieldType.BLOB).withLabel(table.getLabel() + " File").withIsRequired(true))
|
||||||
.withFieldAdornment(FileUploadAdornment.newFieldAdornment()
|
.withComponent(new QFrontendComponentMetaData()
|
||||||
.withValue(FileUploadAdornment.formatDragAndDrop())
|
.withType(QComponentType.HELP_TEXT)
|
||||||
.withValue(FileUploadAdornment.widthFull()))
|
.withValue("previewText", "file upload instructions")
|
||||||
.withLabel(table.getLabel() + " File")
|
.withValue("text", "Upload a CSV file with the following columns:\n" + fieldsForHelpText))
|
||||||
.withIsRequired(true))
|
|
||||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.HTML))
|
|
||||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM));
|
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM));
|
||||||
|
|
||||||
QBackendStepMetaData prepareFileMappingStep = new QBackendStepMetaData()
|
process.addStep(0, uploadScreen);
|
||||||
.withName("prepareFileMapping")
|
process.getFrontendStep("review").setRecordListFields(editableFields);
|
||||||
.withCode(new QCodeReference(BulkInsertPrepareFileMappingStep.class));
|
|
||||||
|
|
||||||
QFrontendStepMetaData fileMappingScreen = new QFrontendStepMetaData()
|
|
||||||
.withName("fileMapping")
|
|
||||||
.withLabel("File Mapping")
|
|
||||||
.withBackStepName("upload")
|
|
||||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.BULK_LOAD_FILE_MAPPING_FORM));
|
|
||||||
|
|
||||||
QBackendStepMetaData receiveFileMappingStep = new QBackendStepMetaData()
|
|
||||||
.withName("receiveFileMapping")
|
|
||||||
.withCode(new QCodeReference(BulkInsertReceiveFileMappingStep.class));
|
|
||||||
|
|
||||||
QBackendStepMetaData prepareValueMappingStep = new QBackendStepMetaData()
|
|
||||||
.withName("prepareValueMapping")
|
|
||||||
.withCode(new QCodeReference(BulkInsertPrepareValueMappingStep.class));
|
|
||||||
|
|
||||||
QFrontendStepMetaData valueMappingScreen = new QFrontendStepMetaData()
|
|
||||||
.withName("valueMapping")
|
|
||||||
.withLabel("Value Mapping")
|
|
||||||
.withBackStepName("prepareFileMapping")
|
|
||||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.BULK_LOAD_VALUE_MAPPING_FORM));
|
|
||||||
|
|
||||||
QBackendStepMetaData receiveValueMappingStep = new QBackendStepMetaData()
|
|
||||||
.withName("receiveValueMapping")
|
|
||||||
.withCode(new QCodeReference(BulkInsertReceiveValueMappingStep.class));
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
process.addStep(i++, prepareFileUploadStep);
|
|
||||||
process.addStep(i++, uploadScreen);
|
|
||||||
|
|
||||||
process.addStep(i++, prepareFileMappingStep);
|
|
||||||
process.addStep(i++, fileMappingScreen);
|
|
||||||
process.addStep(i++, receiveFileMappingStep);
|
|
||||||
|
|
||||||
process.addStep(i++, prepareValueMappingStep);
|
|
||||||
process.addStep(i++, valueMappingScreen);
|
|
||||||
process.addStep(i++, receiveValueMappingStep);
|
|
||||||
|
|
||||||
process.getFrontendStep(StreamedETLWithFrontendProcess.STEP_NAME_REVIEW).setRecordListFields(editableFields);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// put the bulk-load profile form (e.g., for saving it) on the review & result screens) //
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
process.getFrontendStep(StreamedETLWithFrontendProcess.STEP_NAME_REVIEW)
|
|
||||||
.withBackStepName("prepareFileMapping")
|
|
||||||
.getComponents().add(0, new QFrontendComponentMetaData().withType(QComponentType.BULK_LOAD_PROFILE_FORM));
|
|
||||||
|
|
||||||
process.getFrontendStep(StreamedETLWithFrontendProcess.STEP_NAME_RESULT)
|
|
||||||
.getComponents().add(0, new QFrontendComponentMetaData().withType(QComponentType.BULK_LOAD_PROFILE_FORM));
|
|
||||||
|
|
||||||
qInstance.addProcess(process);
|
qInstance.addProcess(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +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.scripts.TestScriptActionInterface;
|
import com.kingsrook.qqq.backend.core.actions.scripts.TestScriptActionInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.values.QCustomPossibleValueProvider;
|
import com.kingsrook.qqq.backend.core.actions.values.QCustomPossibleValueProvider;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||||
@ -75,7 +73,6 @@ 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;
|
||||||
@ -187,7 +184,6 @@ public class QInstanceValidator
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
validateInstanceAttributes(qInstance);
|
|
||||||
validateBackends(qInstance);
|
validateBackends(qInstance);
|
||||||
validateAuthentication(qInstance);
|
validateAuthentication(qInstance);
|
||||||
validateAutomationProviders(qInstance);
|
validateAutomationProviders(qInstance);
|
||||||
@ -228,19 +224,6 @@ public class QInstanceValidator
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private void validateInstanceAttributes(QInstance qInstance)
|
|
||||||
{
|
|
||||||
if(qInstance.getMetaDataFilter() != null)
|
|
||||||
{
|
|
||||||
validateSimpleCodeReference("Instance metaDataFilter ", qInstance.getMetaDataFilter(), MetaDataFilterInterface.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -944,8 +927,13 @@ 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 //
|
||||||
@ -1050,31 +1038,6 @@ 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -1582,16 +1545,6 @@ 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))
|
||||||
@ -1707,12 +1660,9 @@ public class QInstanceValidator
|
|||||||
|
|
||||||
String dataSourceErrorPrefix = "Report " + reportName + " data source " + dataSource.getName() + " ";
|
String dataSourceErrorPrefix = "Report " + reportName + " data source " + dataSource.getName() + " ";
|
||||||
|
|
||||||
boolean hasASource = false;
|
|
||||||
|
|
||||||
if(StringUtils.hasContent(dataSource.getSourceTable()))
|
if(StringUtils.hasContent(dataSource.getSourceTable()))
|
||||||
{
|
{
|
||||||
hasASource = true;
|
assertCondition(dataSource.getStaticDataSupplier() == null, dataSourceErrorPrefix + "has both a sourceTable and a staticDataSupplier (exactly 1 is required).");
|
||||||
assertCondition(dataSource.getStaticDataSupplier() == null, dataSourceErrorPrefix + "has both a sourceTable and a staticDataSupplier (not compatible together).");
|
|
||||||
if(assertCondition(qInstance.getTable(dataSource.getSourceTable()) != null, dataSourceErrorPrefix + "source table " + dataSource.getSourceTable() + " is not a table in this instance."))
|
if(assertCondition(qInstance.getTable(dataSource.getSourceTable()) != null, dataSourceErrorPrefix + "source table " + dataSource.getSourceTable() + " is not a table in this instance."))
|
||||||
{
|
{
|
||||||
if(dataSource.getQueryFilter() != null)
|
if(dataSource.getQueryFilter() != null)
|
||||||
@ -1721,21 +1671,14 @@ public class QInstanceValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(dataSource.getStaticDataSupplier() != null)
|
||||||
if(dataSource.getStaticDataSupplier() != null)
|
|
||||||
{
|
{
|
||||||
assertCondition(dataSource.getCustomRecordSource() == null, dataSourceErrorPrefix + "has both a staticDataSupplier and a customRecordSource (not compatible together).");
|
|
||||||
hasASource = true;
|
|
||||||
validateSimpleCodeReference(dataSourceErrorPrefix, dataSource.getStaticDataSupplier(), Supplier.class);
|
validateSimpleCodeReference(dataSourceErrorPrefix, dataSource.getStaticDataSupplier(), Supplier.class);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if(dataSource.getCustomRecordSource() != null)
|
|
||||||
{
|
{
|
||||||
hasASource = true;
|
errors.add(dataSourceErrorPrefix + "does not have a sourceTable or a staticDataSupplier (exactly 1 is required).");
|
||||||
validateSimpleCodeReference(dataSourceErrorPrefix, dataSource.getCustomRecordSource(), ReportCustomRecordSourceInterface.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assertCondition(hasASource, dataSourceErrorPrefix + "does not have a sourceTable, customRecordSource, or a staticDataSupplier.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1994,93 +1937,83 @@ 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() + ".");
|
||||||
validatePossibleValueSource(qInstance, pvsName, possibleValueSource);
|
if(assertCondition(possibleValueSource.getType() != null, "Missing type for possibleValueSource: " + pvsName))
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 " + 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);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
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.");
|
|
||||||
assertCondition(!CollectionUtils.nullSafeHasContents(possibleValueSource.getSearchFields()), "enum-type possibleValueSource " + name + " should not have searchFields.");
|
|
||||||
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.");
|
|
||||||
|
|
||||||
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."))
|
|
||||||
{
|
|
||||||
tableMetaData = qInstance.getTable(possibleValueSource.getTableName());
|
|
||||||
assertCondition(tableMetaData != null, "Unrecognized table " + possibleValueSource.getTableName() + " for possibleValueSource " + name + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* QQQ - Low-code Application Framework for Engineers.
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
* Copyright (C) 2021-2023. 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,10 +19,12 @@
|
|||||||
* 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.metadata;
|
package com.kingsrook.qqq.backend.core.model;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
@ -31,16 +31,6 @@ 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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
@ -49,190 +39,4 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,6 +29,7 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -40,10 +41,11 @@ public class ProcessState implements Serializable
|
|||||||
private Map<String, Serializable> values = new HashMap<>();
|
private Map<String, Serializable> values = new HashMap<>();
|
||||||
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 Optional<String> backStepName = Optional.empty();
|
|
||||||
private boolean isStepBack = false;
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -124,39 +126,6 @@ public class ProcessState implements Serializable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for backStepName
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public Optional<String> getBackStepName()
|
|
||||||
{
|
|
||||||
return backStepName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for backStepName
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setBackStepName(String backStepName)
|
|
||||||
{
|
|
||||||
this.backStepName = Optional.of(backStepName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** clear out the value of backStepName (set the Optional to empty)
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void clearBackStepName()
|
|
||||||
{
|
|
||||||
this.backStepName = Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for stepList
|
** Getter for stepList
|
||||||
**
|
**
|
||||||
@ -179,67 +148,33 @@ public class ProcessState implements Serializable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for processMetaDataAdjustment
|
** Getter for updatedFrontendStepList
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public ProcessMetaDataAdjustment getProcessMetaDataAdjustment()
|
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
||||||
{
|
{
|
||||||
return (this.processMetaDataAdjustment);
|
return (this.updatedFrontendStepList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for processMetaDataAdjustment
|
** Setter for updatedFrontendStepList
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
{
|
{
|
||||||
this.processMetaDataAdjustment = processMetaDataAdjustment;
|
this.updatedFrontendStepList = updatedFrontendStepList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Fluent setter for processMetaDataAdjustment
|
** Fluent setter for updatedFrontendStepList
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public ProcessState withProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
public ProcessState withUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
{
|
{
|
||||||
this.processMetaDataAdjustment = processMetaDataAdjustment;
|
this.updatedFrontendStepList = updatedFrontendStepList;
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for isStepBack
|
|
||||||
*******************************************************************************/
|
|
||||||
public boolean getIsStepBack()
|
|
||||||
{
|
|
||||||
return (this.isStepBack);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for isStepBack
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setIsStepBack(boolean isStepBack)
|
|
||||||
{
|
|
||||||
this.isStepBack = isStepBack;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for isStepBack
|
|
||||||
*******************************************************************************/
|
|
||||||
public ProcessState withIsStepBack(boolean isStepBack)
|
|
||||||
{
|
|
||||||
this.isStepBack = isStepBack;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ public class ProcessSummaryLine implements ProcessSummaryLineInterface
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
private ArrayList<Serializable> primaryKeys;
|
private ArrayList<Serializable> primaryKeys;
|
||||||
|
|
||||||
private ArrayList<String> bulletsOfText;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -498,35 +497,4 @@ public class ProcessSummaryLine implements ProcessSummaryLineInterface
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for bulletsOfText
|
|
||||||
*******************************************************************************/
|
|
||||||
public ArrayList<String> getBulletsOfText()
|
|
||||||
{
|
|
||||||
return (this.bulletsOfText);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for bulletsOfText
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setBulletsOfText(ArrayList<String> bulletsOfText)
|
|
||||||
{
|
|
||||||
this.bulletsOfText = bulletsOfText;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for bulletsOfText
|
|
||||||
*******************************************************************************/
|
|
||||||
public ProcessSummaryLine withBulletsOfText(ArrayList<String> bulletsOfText)
|
|
||||||
{
|
|
||||||
this.bulletsOfText = bulletsOfText;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -419,17 +419,6 @@ public class RunBackendStepInput extends AbstractActionInput
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Accessor for processState's isStepBack attribute
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public boolean getIsStepBack()
|
|
||||||
{
|
|
||||||
return processState.getIsStepBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Accessor for processState - protected, because we generally want to access
|
** Accessor for processState - protected, because we generally want to access
|
||||||
** its members through wrapper methods, we think
|
** its members through wrapper methods, we think
|
||||||
|
@ -374,13 +374,7 @@ public class RunBackendStepOutput extends AbstractActionOutput implements Serial
|
|||||||
.map(step -> (QFrontendStepMetaData) step)
|
.map(step -> (QFrontendStepMetaData) step)
|
||||||
.toList());
|
.toList());
|
||||||
|
|
||||||
ProcessMetaDataAdjustment processMetaDataAdjustment = getProcessMetaDataAdjustment();
|
setUpdatedFrontendStepList(updatedFrontendStepList);
|
||||||
if(processMetaDataAdjustment == null)
|
|
||||||
{
|
|
||||||
processMetaDataAdjustment = new ProcessMetaDataAdjustment();
|
|
||||||
}
|
|
||||||
processMetaDataAdjustment.setUpdatedFrontendStepList(updatedFrontendStepList);
|
|
||||||
setProcessMetaDataAdjustment(processMetaDataAdjustment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -417,21 +411,21 @@ public class RunBackendStepOutput extends AbstractActionOutput implements Serial
|
|||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for ProcessMetaDataAdjustment (pass-through to processState)
|
** Getter for updatedFrontendStepList
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public ProcessMetaDataAdjustment getProcessMetaDataAdjustment()
|
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
||||||
{
|
{
|
||||||
return (this.processState.getProcessMetaDataAdjustment());
|
return (this.processState.getUpdatedFrontendStepList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Setter for updatedFrontendStepList (pass-through to processState)
|
** Setter for updatedFrontendStepList
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
{
|
{
|
||||||
this.processState.setProcessMetaDataAdjustment(processMetaDataAdjustment);
|
this.processState.setUpdatedFrontendStepList(updatedFrontendStepList);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@ public class RunProcessInput extends AbstractActionInput
|
|||||||
private ProcessState processState;
|
private ProcessState processState;
|
||||||
private FrontendStepBehavior frontendStepBehavior = FrontendStepBehavior.BREAK;
|
private FrontendStepBehavior frontendStepBehavior = FrontendStepBehavior.BREAK;
|
||||||
private String startAfterStep;
|
private String startAfterStep;
|
||||||
private String startAtStep;
|
|
||||||
private String processUUID;
|
private String processUUID;
|
||||||
private AsyncJobCallback asyncJobCallback;
|
private AsyncJobCallback asyncJobCallback;
|
||||||
|
|
||||||
@ -452,35 +451,4 @@ public class RunProcessInput extends AbstractActionInput
|
|||||||
{
|
{
|
||||||
return asyncJobCallback;
|
return asyncJobCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for startAtStep
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getStartAtStep()
|
|
||||||
{
|
|
||||||
return (this.startAtStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for startAtStep
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setStartAtStep(String startAtStep)
|
|
||||||
{
|
|
||||||
this.startAtStep = startAtStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for startAtStep
|
|
||||||
*******************************************************************************/
|
|
||||||
public RunProcessInput withStartAtStep(String startAtStep)
|
|
||||||
{
|
|
||||||
this.startAtStep = startAtStep;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -33,7 +33,6 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
@ -337,12 +336,7 @@ public class RunProcessOutput extends AbstractActionOutput implements Serializab
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
public void setUpdatedFrontendStepList(List<QFrontendStepMetaData> updatedFrontendStepList)
|
||||||
{
|
{
|
||||||
if(this.processState.getProcessMetaDataAdjustment() == null)
|
this.processState.setUpdatedFrontendStepList(updatedFrontendStepList);
|
||||||
{
|
|
||||||
this.processState.setProcessMetaDataAdjustment(new ProcessMetaDataAdjustment());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.processState.getProcessMetaDataAdjustment().setUpdatedFrontendStepList(updatedFrontendStepList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -352,27 +346,7 @@ public class RunProcessOutput extends AbstractActionOutput implements Serializab
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
public List<QFrontendStepMetaData> getUpdatedFrontendStepList()
|
||||||
{
|
{
|
||||||
return ObjectUtils.tryElse(() -> this.processState.getProcessMetaDataAdjustment().getUpdatedFrontendStepList(), null);
|
return this.processState.getUpdatedFrontendStepList();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for processMetaDataAdjustment
|
|
||||||
*******************************************************************************/
|
|
||||||
public ProcessMetaDataAdjustment getProcessMetaDataAdjustment()
|
|
||||||
{
|
|
||||||
return (this.processState.getProcessMetaDataAdjustment());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for processMetaDataAdjustment
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setProcessMetaDataAdjustment(ProcessMetaDataAdjustment processMetaDataAdjustment)
|
|
||||||
{
|
|
||||||
this.processState.setProcessMetaDataAdjustment(processMetaDataAdjustment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.tables.query;
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
** Possible behaviors for doing interpretValues on a filter, and a criteria
|
|
||||||
** has a variable value (either as a string-that-looks-like-a-variable,
|
|
||||||
** as in ${input.foreignId} for a PVS filter, or a FilterVariableExpression),
|
|
||||||
** and a value for that variable isn't available.
|
|
||||||
**
|
|
||||||
** Used in conjunction with FilterUseCase and its implementations, e.g.,
|
|
||||||
** PossibleValueSearchFilterUseCase.
|
|
||||||
***************************************************************************/
|
|
||||||
public enum CriteriaMissingInputValueBehavior
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// this was the original behavior, before we added this enum. but, //
|
|
||||||
// it doesn't ever seem entirely valid, and isn't currently used. //
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
INTERPRET_AS_NULL_VALUE,
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// make the criteria behave as though it's not in the filter at all. //
|
|
||||||
// effectively by changing its operator to TRUE, so it always matches. //
|
|
||||||
// original intended use is for possible-values on query screens, //
|
|
||||||
// where a foreign-id isn't present, so we want to show all PV options. //
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
REMOVE_FROM_FILTER,
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// make the criteria such that it makes no rows ever match. //
|
|
||||||
// e.g., changes it to a FALSE. I suppose, within an OR, that might //
|
|
||||||
// not be powerful enough... but, it solves the immediate use-case in //
|
|
||||||
// front of us, which is forms, where a PV field should show no values //
|
|
||||||
// until a foreign key field has a value. //
|
|
||||||
// Note that this use-case used to have the same end-effect by such //
|
|
||||||
// variables being interpreted as nulls - but this approach feels more intentional. //
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
MAKE_NO_MATCHES,
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// throw an exception if a value isn't available. This is the overall default, //
|
|
||||||
// and originally was what we did for FilterVariableExpressions, e.g., for saved reports //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
THROW_EXCEPTION
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.tables.query;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Interface where we can associate behaviors with various use cases for
|
|
||||||
** QQueryFilters - the original being, how to handle (in the interpretValues
|
|
||||||
** method) how to handle missing input values.
|
|
||||||
**
|
|
||||||
** Includes a default implementation, with a default behavior - which is to
|
|
||||||
** throw an exception upon missing criteria variable values.
|
|
||||||
*******************************************************************************/
|
|
||||||
public interface FilterUseCase
|
|
||||||
{
|
|
||||||
FilterUseCase DEFAULT = new DefaultFilterUseCase();
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
CriteriaMissingInputValueBehavior getDefaultCriteriaMissingInputValueBehavior();
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
class DefaultFilterUseCase implements FilterUseCase
|
|
||||||
{
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
@Override
|
|
||||||
public CriteriaMissingInputValueBehavior getDefaultCriteriaMissingInputValueBehavior()
|
|
||||||
{
|
|
||||||
return CriteriaMissingInputValueBehavior.THROW_EXCEPTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -82,7 +82,7 @@ public class JoinsContext
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// we will get a TON of more output if this gets turned up, so be cautious //
|
// we will get a TON of more output if this gets turned up, so be cautious //
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
private Level logLevel = Level.OFF;
|
private Level logLevel = Level.OFF;
|
||||||
private Level logLevelForFilter = Level.OFF;
|
private Level logLevelForFilter = Level.OFF;
|
||||||
|
|
||||||
|
|
||||||
@ -404,12 +404,6 @@ public class JoinsContext
|
|||||||
chainIsInner = false;
|
chainIsInner = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasAllAccessKey(recordSecurityLock))
|
|
||||||
{
|
|
||||||
queryJoin.withType(QueryJoin.Type.LEFT);
|
|
||||||
chainIsInner = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
addQueryJoin(queryJoin, "forRecordSecurityLock (non-flipped)", "- ");
|
addQueryJoin(queryJoin, "forRecordSecurityLock (non-flipped)", "- ");
|
||||||
addedQueryJoins.add(queryJoin);
|
addedQueryJoins.add(queryJoin);
|
||||||
tmpTable = instance.getTable(join.getRightTable());
|
tmpTable = instance.getTable(join.getRightTable());
|
||||||
@ -429,12 +423,6 @@ public class JoinsContext
|
|||||||
chainIsInner = false;
|
chainIsInner = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasAllAccessKey(recordSecurityLock))
|
|
||||||
{
|
|
||||||
queryJoin.withType(QueryJoin.Type.LEFT);
|
|
||||||
chainIsInner = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
addQueryJoin(queryJoin, "forRecordSecurityLock (flipped)", "- ");
|
addQueryJoin(queryJoin, "forRecordSecurityLock (flipped)", "- ");
|
||||||
addedQueryJoins.add(queryJoin);
|
addedQueryJoins.add(queryJoin);
|
||||||
tmpTable = instance.getTable(join.getLeftTable());
|
tmpTable = instance.getTable(join.getLeftTable());
|
||||||
@ -468,53 +456,44 @@ public class JoinsContext
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private boolean hasAllAccessKey(RecordSecurityLock recordSecurityLock)
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// check if the key type has an all-access key, and if so, if it's set to true for the current user/session //
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
QSecurityKeyType securityKeyType = instance.getSecurityKeyType(recordSecurityLock.getSecurityKeyType());
|
|
||||||
if(StringUtils.hasContent(securityKeyType.getAllAccessKeyName()))
|
|
||||||
{
|
|
||||||
QSession session = QContext.getQSession();
|
|
||||||
if(session.hasSecurityKeyValue(securityKeyType.getAllAccessKeyName(), true, QFieldType.BOOLEAN))
|
|
||||||
{
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private void addSubFilterForRecordSecurityLock(RecordSecurityLock recordSecurityLock, QTableMetaData table, String tableNameOrAlias, boolean isOuter, QueryJoin sourceQueryJoin)
|
private void addSubFilterForRecordSecurityLock(RecordSecurityLock recordSecurityLock, QTableMetaData table, String tableNameOrAlias, boolean isOuter, QueryJoin sourceQueryJoin)
|
||||||
{
|
{
|
||||||
boolean haveAllAccessKey = hasAllAccessKey(recordSecurityLock);
|
QSession session = QContext.getQSession();
|
||||||
if(haveAllAccessKey)
|
|
||||||
{
|
|
||||||
if(sourceQueryJoin != null)
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// in case the queryJoin object is re-used between queries, and its security criteria need to be different (!!), reset it //
|
|
||||||
// this can be exposed in tests - maybe not entirely expected in real-world, but seems safe enough //
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
sourceQueryJoin.withSecurityCriteria(new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// if we're in an AND filter, then we don't need a criteria for this lock, so return. //
|
// check if the key type has an all-access key, and if so, if it's set to true for the current user/session //
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
boolean inAnAndFilter = securityFilterCursor.getBooleanOperator() == QQueryFilter.BooleanOperator.AND;
|
QSecurityKeyType securityKeyType = instance.getSecurityKeyType(recordSecurityLock.getSecurityKeyType());
|
||||||
if(inAnAndFilter)
|
boolean haveAllAccessKey = false;
|
||||||
|
if(StringUtils.hasContent(securityKeyType.getAllAccessKeyName()))
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if we have all-access on this key, then we don't need a criterion for it (as long as we're in an AND filter) //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(session.hasSecurityKeyValue(securityKeyType.getAllAccessKeyName(), true, QFieldType.BOOLEAN))
|
||||||
{
|
{
|
||||||
return;
|
haveAllAccessKey = true;
|
||||||
|
|
||||||
|
if(sourceQueryJoin != null)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// in case the queryJoin object is re-used between queries, and its security criteria need to be different (!!), reset it //
|
||||||
|
// this can be exposed in tests - maybe not entirely expected in real-world, but seems safe enough //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
sourceQueryJoin.withSecurityCriteria(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if we're in an AND filter, then we don't need a criteria for this lock, so return. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
boolean inAnAndFilter = securityFilterCursor.getBooleanOperator() == QQueryFilter.BooleanOperator.AND;
|
||||||
|
if(inAnAndFilter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +545,7 @@ public class JoinsContext
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<Serializable> securityKeyValues = QContext.getQSession().getSecurityKeyValues(recordSecurityLock.getSecurityKeyType(), type);
|
List<Serializable> securityKeyValues = session.getSecurityKeyValues(recordSecurityLock.getSecurityKeyType(), type);
|
||||||
if(CollectionUtils.nullSafeIsEmpty(securityKeyValues))
|
if(CollectionUtils.nullSafeIsEmpty(securityKeyValues))
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -528,27 +528,8 @@ public class QQueryFilter implements Serializable, Cloneable
|
|||||||
** Note - it may be very important that you call this method on a clone of a
|
** Note - it may be very important that you call this method on a clone of a
|
||||||
** QQueryFilter - e.g., if it's one that defined in metaData, and that we don't
|
** QQueryFilter - e.g., if it's one that defined in metaData, and that we don't
|
||||||
** want to be (permanently) changed!!
|
** want to be (permanently) changed!!
|
||||||
**
|
|
||||||
** This overload does not take in a FilterUseCase - it uses FilterUseCase.DEFAULT
|
|
||||||
******************************************************************************/
|
|
||||||
public void interpretValues(Map<String, Serializable> inputValues) throws QException
|
|
||||||
{
|
|
||||||
interpretValues(inputValues, FilterUseCase.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Replace any criteria values that look like ${input.XXX} with the value of XXX
|
|
||||||
** from the supplied inputValues map - where the handling of missing values
|
|
||||||
** is specified in the inputted FilterUseCase parameter
|
|
||||||
**
|
|
||||||
** Note - it may be very important that you call this method on a clone of a
|
|
||||||
** QQueryFilter - e.g., if it's one that defined in metaData, and that we don't
|
|
||||||
** want to be (permanently) changed!!
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public void interpretValues(Map<String, Serializable> inputValues, FilterUseCase useCase) throws QException
|
public void interpretValues(Map<String, Serializable> inputValues) throws QException
|
||||||
{
|
{
|
||||||
List<Exception> caughtExceptions = new ArrayList<>();
|
List<Exception> caughtExceptions = new ArrayList<>();
|
||||||
|
|
||||||
@ -564,9 +545,6 @@ public class QQueryFilter implements Serializable, Cloneable
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Serializable interpretedValue = value;
|
|
||||||
Exception caughtException = null;
|
|
||||||
|
|
||||||
if(value instanceof AbstractFilterExpression<?>)
|
if(value instanceof AbstractFilterExpression<?>)
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
@ -575,54 +553,17 @@ public class QQueryFilter implements Serializable, Cloneable
|
|||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
if(value instanceof FilterVariableExpression filterVariableExpression)
|
if(value instanceof FilterVariableExpression filterVariableExpression)
|
||||||
{
|
{
|
||||||
try
|
newValues.add(filterVariableExpression.evaluateInputValues(inputValues));
|
||||||
{
|
|
||||||
interpretedValue = filterVariableExpression.evaluateInputValues(inputValues);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
caughtException = e;
|
|
||||||
interpretedValue = InputNotFound.instance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// for non-expressions, cast the value to a string, and see if it can be resolved a variable. //
|
|
||||||
// there are 3 possible cases here: //
|
|
||||||
// 1: it doesn't look like a variable, so it just comes back as a string version of whatever went in. //
|
|
||||||
// 2: it was resolved from a variable to a value, e.g., ${input.someVar} => someValue //
|
|
||||||
// 3: it looked like a variable, but no value for that variable was present in the interpreter's value //
|
|
||||||
// map - so we'll get back the InputNotFound.instance. //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
String valueAsString = ValueUtils.getValueAsString(value);
|
|
||||||
interpretedValue = variableInterpreter.interpretForObject(valueAsString, InputNotFound.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// if interpreting a value returned the not-found value, or an empty string, //
|
|
||||||
// then decide how to handle the missing value, based on the use-case input //
|
|
||||||
// Note: questionable, using "" here, but that's what reality is passing a lot for cases we want to treat as missing... //
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
if(interpretedValue == InputNotFound.instance || "".equals(interpretedValue))
|
|
||||||
{
|
|
||||||
CriteriaMissingInputValueBehavior missingInputValueBehavior = getMissingInputValueBehavior(useCase);
|
|
||||||
|
|
||||||
switch(missingInputValueBehavior)
|
|
||||||
{
|
{
|
||||||
case REMOVE_FROM_FILTER -> criterion.setOperator(QCriteriaOperator.TRUE);
|
newValues.add(value);
|
||||||
case MAKE_NO_MATCHES -> criterion.setOperator(QCriteriaOperator.FALSE);
|
|
||||||
case INTERPRET_AS_NULL_VALUE -> newValues.add(null);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
// handle case in the default: THROW_EXCEPTION //
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
default -> throw (Objects.requireNonNullElseGet(caughtException, () -> new QUserFacingException("Missing value for criteria on field: " + criterion.getFieldName())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
String valueAsString = ValueUtils.getValueAsString(value);
|
||||||
|
Serializable interpretedValue = variableInterpreter.interpretForObject(valueAsString);
|
||||||
newValues.add(interpretedValue);
|
newValues.add(interpretedValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -645,44 +586,6 @@ public class QQueryFilter implements Serializable, Cloneable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
** Note: in the original build of this, it felt like we *might* want to be
|
|
||||||
** able to specify these behaviors at the individual criteria level, where
|
|
||||||
** the implementation would be to add to QFilterCriteria:
|
|
||||||
** - Map<FilterUseCase, CriteriaMissingInputValueBehavior> missingInputValueBehaviors;
|
|
||||||
** - CriteriaMissingInputValueBehavior getMissingInputValueBehaviorForUseCase(FilterUseCase useCase) {}
|
|
||||||
*
|
|
||||||
** (and maybe do that in a sub-class of QFilterCriteria, so it isn't always
|
|
||||||
** there? idk...) and then here we'd call:
|
|
||||||
** - CriteriaMissingInputValueBehavior missingInputValueBehavior = criterion.getMissingInputValueBehaviorForUseCase(useCase);
|
|
||||||
*
|
|
||||||
** But, we don't actually have that use-case at hand now, so - let's keep it
|
|
||||||
** just at the level we need for now.
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private CriteriaMissingInputValueBehavior getMissingInputValueBehavior(FilterUseCase useCase)
|
|
||||||
{
|
|
||||||
if(useCase == null)
|
|
||||||
{
|
|
||||||
useCase = FilterUseCase.DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
CriteriaMissingInputValueBehavior missingInputValueBehavior = useCase.getDefaultCriteriaMissingInputValueBehavior();
|
|
||||||
if(missingInputValueBehavior == null)
|
|
||||||
{
|
|
||||||
missingInputValueBehavior = useCase.getDefaultCriteriaMissingInputValueBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(missingInputValueBehavior == null)
|
|
||||||
{
|
|
||||||
missingInputValueBehavior = FilterUseCase.DEFAULT.getDefaultCriteriaMissingInputValueBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (missingInputValueBehavior);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for skip
|
** Getter for skip
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -775,28 +678,4 @@ public class QQueryFilter implements Serializable, Cloneable
|
|||||||
{
|
{
|
||||||
return Objects.hash(criteria, orderBys, booleanOperator, subFilters, skip, limit);
|
return Objects.hash(criteria, orderBys, booleanOperator, subFilters, skip, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
** "Token" object to be used as the defaultIfLooksLikeVariableButNotFound
|
|
||||||
** parameter to variableInterpreter.interpretForObject, so we can be
|
|
||||||
** very clear that we got this default back (e.g., instead of a null,
|
|
||||||
** which could maybe mean something else?)
|
|
||||||
***************************************************************************/
|
|
||||||
private static final class InputNotFound implements Serializable
|
|
||||||
{
|
|
||||||
private static InputNotFound instance = new InputNotFound();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** private singleton constructor
|
|
||||||
*******************************************************************************/
|
|
||||||
private InputNotFound()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,14 +66,6 @@ public class QueryInput extends AbstractTableActionInput implements QueryOrGetIn
|
|||||||
private List<QueryJoin> queryJoins = null;
|
private List<QueryJoin> queryJoins = null;
|
||||||
private boolean selectDistinct = false;
|
private boolean selectDistinct = false;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// if this set is null, then the default (all fields) should be included //
|
|
||||||
// if it's an empty set, that should throw an error //
|
|
||||||
// or if there are any fields in it that aren't valid fields on the table, //
|
|
||||||
// or in a selected queryJoin. //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
private Set<String> fieldNamesToInclude;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// if you say you want to includeAssociations, you can limit which ones by passing them in associationNamesToInclude. //
|
// if you say you want to includeAssociations, you can limit which ones by passing them in associationNamesToInclude. //
|
||||||
// if you leave it null, you get all associations defined on the table. if you pass it as empty, you get none. //
|
// if you leave it null, you get all associations defined on the table. if you pass it as empty, you get none. //
|
||||||
@ -694,35 +686,4 @@ public class QueryInput extends AbstractTableActionInput implements QueryOrGetIn
|
|||||||
return (queryHints.contains(queryHint));
|
return (queryHints.contains(queryHint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for fieldNamesToInclude
|
|
||||||
*******************************************************************************/
|
|
||||||
public Set<String> getFieldNamesToInclude()
|
|
||||||
{
|
|
||||||
return (this.fieldNamesToInclude);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for fieldNamesToInclude
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setFieldNamesToInclude(Set<String> fieldNamesToInclude)
|
|
||||||
{
|
|
||||||
this.fieldNamesToInclude = fieldNamesToInclude;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for fieldNamesToInclude
|
|
||||||
*******************************************************************************/
|
|
||||||
public QueryInput withFieldNamesToInclude(Set<String> fieldNamesToInclude)
|
|
||||||
{
|
|
||||||
this.fieldNamesToInclude = fieldNamesToInclude;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -36,7 +35,7 @@ public abstract class AbstractFilterExpression<T extends Serializable> implement
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public abstract T evaluate(QFieldMetaData field) throws QException;
|
public abstract T evaluate() throws QException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ public abstract class AbstractFilterExpression<T extends Serializable> implement
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public T evaluateInputValues(Map<String, Serializable> inputValues) throws QException
|
public T evaluateInputValues(Map<String, Serializable> inputValues) throws QException
|
||||||
{
|
{
|
||||||
return evaluate(null);
|
return evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import java.io.Serializable;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
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.metadata.fields.QFieldMetaData;
|
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ public class FilterVariableExpression extends AbstractFilterExpression<Serializa
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Override
|
@Override
|
||||||
public Serializable evaluate(QFieldMetaData field) throws QException
|
public Serializable evaluate() throws QException
|
||||||
{
|
{
|
||||||
throw (new QUserFacingException("Missing variable value."));
|
throw (new QUserFacingException("Missing variable value."));
|
||||||
}
|
}
|
||||||
|
@ -22,42 +22,23 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
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.utils.ValueUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class Now extends AbstractFilterExpression<Serializable>
|
public class Now extends AbstractFilterExpression<Instant>
|
||||||
{
|
{
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Override
|
@Override
|
||||||
public Serializable evaluate(QFieldMetaData field) throws QException
|
public Instant evaluate() throws QException
|
||||||
{
|
{
|
||||||
QFieldType type = field == null ? QFieldType.DATE_TIME : field.getType();
|
return (Instant.now());
|
||||||
|
|
||||||
if(type.equals(QFieldType.DATE_TIME))
|
|
||||||
{
|
|
||||||
return (Instant.now());
|
|
||||||
}
|
|
||||||
else if(type.equals(QFieldType.DATE))
|
|
||||||
{
|
|
||||||
ZoneId zoneId = ValueUtils.getSessionOrInstanceZoneId();
|
|
||||||
return (Instant.now().atZone(zoneId).toLocalDate());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw (new QException("Unsupported field type [" + type + "]"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,24 +22,19 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
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.utils.ValueUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class NowWithOffset extends AbstractFilterExpression<Serializable>
|
public class NowWithOffset extends AbstractFilterExpression<Instant>
|
||||||
{
|
{
|
||||||
private Operator operator;
|
private Operator operator;
|
||||||
private int amount;
|
private int amount;
|
||||||
@ -128,30 +123,7 @@ public class NowWithOffset extends AbstractFilterExpression<Serializable>
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Override
|
@Override
|
||||||
public Serializable evaluate(QFieldMetaData field) throws QException
|
public Instant evaluate() throws QException
|
||||||
{
|
|
||||||
QFieldType type = field == null ? QFieldType.DATE_TIME : field.getType();
|
|
||||||
|
|
||||||
if(type.equals(QFieldType.DATE_TIME))
|
|
||||||
{
|
|
||||||
return (evaluateForDateTime());
|
|
||||||
}
|
|
||||||
else if(type.equals(QFieldType.DATE))
|
|
||||||
{
|
|
||||||
return (evaluateForDate());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw (new QException("Unsupported field type [" + type + "]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private Instant evaluateForDateTime()
|
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Instant doesn't let us plus/minus WEEK, MONTH, or YEAR... //
|
// Instant doesn't let us plus/minus WEEK, MONTH, or YEAR... //
|
||||||
@ -175,26 +147,6 @@ public class NowWithOffset extends AbstractFilterExpression<Serializable>
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private LocalDate evaluateForDate()
|
|
||||||
{
|
|
||||||
ZoneId zoneId = ValueUtils.getSessionOrInstanceZoneId();
|
|
||||||
LocalDate now = Instant.now().atZone(zoneId).toLocalDate();
|
|
||||||
|
|
||||||
if(operator.equals(Operator.PLUS))
|
|
||||||
{
|
|
||||||
return (now.plus(amount, timeUnit));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (now.minus(amount, timeUnit));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for operator
|
** Getter for operator
|
||||||
**
|
**
|
||||||
|
@ -22,32 +22,27 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
package com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions;
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.DayOfWeek;
|
import java.time.DayOfWeek;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.temporal.ChronoField;
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
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.exceptions.QRuntimeException;
|
||||||
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.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class ThisOrLastPeriod extends AbstractFilterExpression<Serializable>
|
public class ThisOrLastPeriod extends AbstractFilterExpression<Instant>
|
||||||
{
|
{
|
||||||
private Operator operator;
|
private Operator operator;
|
||||||
private ChronoUnit timeUnit;
|
private ChronoUnit timeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
**
|
**
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -93,7 +88,7 @@ public class ThisOrLastPeriod extends AbstractFilterExpression<Serializable>
|
|||||||
** Factory
|
** Factory
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static ThisOrLastPeriod last(ChronoUnit timeUnit)
|
public static ThisOrLastPeriod last(int amount, ChronoUnit timeUnit)
|
||||||
{
|
{
|
||||||
return (new ThisOrLastPeriod(Operator.LAST, timeUnit));
|
return (new ThisOrLastPeriod(Operator.LAST, timeUnit));
|
||||||
}
|
}
|
||||||
@ -104,31 +99,7 @@ public class ThisOrLastPeriod extends AbstractFilterExpression<Serializable>
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Override
|
@Override
|
||||||
public Serializable evaluate(QFieldMetaData field) throws QException
|
public Instant evaluate() throws QException
|
||||||
{
|
|
||||||
QFieldType type = field == null ? QFieldType.DATE_TIME : field.getType();
|
|
||||||
|
|
||||||
if(type.equals(QFieldType.DATE_TIME))
|
|
||||||
{
|
|
||||||
return (evaluateForDateTime());
|
|
||||||
}
|
|
||||||
else if(type.equals(QFieldType.DATE))
|
|
||||||
{
|
|
||||||
// return (evaluateForDateTime());
|
|
||||||
return (evaluateForDate());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw (new QException("Unsupported field type [" + type + "]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private Instant evaluateForDateTime()
|
|
||||||
{
|
{
|
||||||
ZoneId zoneId = ValueUtils.getSessionOrInstanceZoneId();
|
ZoneId zoneId = ValueUtils.getSessionOrInstanceZoneId();
|
||||||
|
|
||||||
@ -183,57 +154,7 @@ public class ThisOrLastPeriod extends AbstractFilterExpression<Serializable>
|
|||||||
|
|
||||||
return operator.equals(Operator.THIS) ? startOfThisYear : startOfLastYear;
|
return operator.equals(Operator.THIS) ? startOfThisYear : startOfLastYear;
|
||||||
}
|
}
|
||||||
default -> throw (new QRuntimeException("Unsupported unit: " + timeUnit));
|
default -> throw (new QRuntimeException("Unsupported timeUnit: " + timeUnit));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public LocalDate evaluateForDate()
|
|
||||||
{
|
|
||||||
ZoneId zoneId = ValueUtils.getSessionOrInstanceZoneId();
|
|
||||||
LocalDate today = Instant.now().atZone(zoneId).toLocalDate();
|
|
||||||
|
|
||||||
switch(timeUnit)
|
|
||||||
{
|
|
||||||
case DAYS ->
|
|
||||||
{
|
|
||||||
return operator.equals(Operator.THIS) ? today : today.minusDays(1);
|
|
||||||
}
|
|
||||||
case WEEKS ->
|
|
||||||
{
|
|
||||||
LocalDate startOfThisWeek = today;
|
|
||||||
while(startOfThisWeek.get(ChronoField.DAY_OF_WEEK) != DayOfWeek.SUNDAY.getValue())
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// go backwards until sunday is found //
|
|
||||||
////////////////////////////////////////
|
|
||||||
startOfThisWeek = startOfThisWeek.minusDays(1);
|
|
||||||
}
|
|
||||||
return operator.equals(Operator.THIS) ? startOfThisWeek : startOfThisWeek.minusDays(7);
|
|
||||||
}
|
|
||||||
case MONTHS ->
|
|
||||||
{
|
|
||||||
Instant startOfThisMonth = ValueUtils.getStartOfMonthInZoneId(zoneId.getId());
|
|
||||||
LocalDateTime startOfThisMonthLDT = LocalDateTime.ofInstant(startOfThisMonth, ZoneId.of(zoneId.getId()));
|
|
||||||
LocalDateTime startOfLastMonthLDT = startOfThisMonthLDT.minusMonths(1);
|
|
||||||
Instant startOfLastMonth = startOfLastMonthLDT.toInstant(ZoneId.of(zoneId.getId()).getRules().getOffset(Instant.now()));
|
|
||||||
|
|
||||||
return (operator.equals(Operator.THIS) ? startOfThisMonth : startOfLastMonth).atZone(zoneId).toLocalDate();
|
|
||||||
}
|
|
||||||
case YEARS ->
|
|
||||||
{
|
|
||||||
Instant startOfThisYear = ValueUtils.getStartOfYearInZoneId(zoneId.getId());
|
|
||||||
LocalDateTime startOfThisYearLDT = LocalDateTime.ofInstant(startOfThisYear, zoneId);
|
|
||||||
LocalDateTime startOfLastYearLDT = startOfThisYearLDT.minusYears(1);
|
|
||||||
Instant startOfLastYear = startOfLastYearLDT.toInstant(zoneId.getRules().getOffset(Instant.now()));
|
|
||||||
|
|
||||||
return (operator.equals(Operator.THIS) ? startOfThisYear : startOfLastYear).atZone(zoneId).toLocalDate();
|
|
||||||
}
|
|
||||||
default -> throw (new QRuntimeException("Unsupported unit: " + timeUnit));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,17 +22,15 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.actions.tables.storage;
|
package com.kingsrook.qqq.backend.core.model.actions.tables.storage;
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Input for Storage actions.
|
** Input for Storage actions.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class StorageInput extends AbstractTableActionInput implements Serializable
|
public class StorageInput extends AbstractTableActionInput
|
||||||
{
|
{
|
||||||
private String reference;
|
private String reference;
|
||||||
private String contentType;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -76,35 +74,4 @@ public class StorageInput extends AbstractTableActionInput implements Serializab
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for contentType
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getContentType()
|
|
||||||
{
|
|
||||||
return (this.contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for contentType
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setContentType(String contentType)
|
|
||||||
{
|
|
||||||
this.contentType = contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for contentType
|
|
||||||
*******************************************************************************/
|
|
||||||
public StorageInput withContentType(String contentType)
|
|
||||||
{
|
|
||||||
this.contentType = contentType;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,9 @@ public class SearchPossibleValueSourceInput extends AbstractActionInput implemen
|
|||||||
private QQueryFilter defaultQueryFilter;
|
private QQueryFilter defaultQueryFilter;
|
||||||
private String searchTerm;
|
private String searchTerm;
|
||||||
private List<Serializable> idList;
|
private List<Serializable> idList;
|
||||||
private List<String> labelList;
|
|
||||||
|
|
||||||
private Integer skip = 0;
|
private Integer skip = 0;
|
||||||
private Integer limit = 250;
|
private Integer limit = 100;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -282,35 +281,4 @@ public class SearchPossibleValueSourceInput extends AbstractActionInput implemen
|
|||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for labelList
|
|
||||||
*******************************************************************************/
|
|
||||||
public List<String> getLabelList()
|
|
||||||
{
|
|
||||||
return (this.labelList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for labelList
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setLabelList(List<String> labelList)
|
|
||||||
{
|
|
||||||
this.labelList = labelList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for labelList
|
|
||||||
*******************************************************************************/
|
|
||||||
public SearchPossibleValueSourceInput withLabelList(List<String> labelList)
|
|
||||||
{
|
|
||||||
this.labelList = labelList;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ public class SearchPossibleValueSourceOutput extends AbstractActionOutput
|
|||||||
{
|
{
|
||||||
private List<QPossibleValue<?>> results = new ArrayList<>();
|
private List<QPossibleValue<?>> results = new ArrayList<>();
|
||||||
|
|
||||||
private String warning;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -89,35 +88,4 @@ public class SearchPossibleValueSourceOutput extends AbstractActionOutput
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for warning
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getWarning()
|
|
||||||
{
|
|
||||||
return (this.warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for warning
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setWarning(String warning)
|
|
||||||
{
|
|
||||||
this.warning = warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for warning
|
|
||||||
*******************************************************************************/
|
|
||||||
public SearchPossibleValueSourceOutput withWarning(String warning)
|
|
||||||
{
|
|
||||||
this.warning = warning;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ public class AuditsMetaDataProvider
|
|||||||
.withRecordLabelFormat("%s %s")
|
.withRecordLabelFormat("%s %s")
|
||||||
.withRecordLabelFields("auditTableId", "recordId")
|
.withRecordLabelFields("auditTableId", "recordId")
|
||||||
.withPrimaryKeyField("id")
|
.withPrimaryKeyField("id")
|
||||||
.withField(new QFieldMetaData("id", QFieldType.LONG))
|
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
|
||||||
.withField(new QFieldMetaData("auditTableId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT_TABLE))
|
.withField(new QFieldMetaData("auditTableId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT_TABLE))
|
||||||
.withField(new QFieldMetaData("auditUserId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT_USER))
|
.withField(new QFieldMetaData("auditUserId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT_USER))
|
||||||
.withField(new QFieldMetaData("recordId", QFieldType.INTEGER))
|
.withField(new QFieldMetaData("recordId", QFieldType.INTEGER))
|
||||||
@ -243,8 +243,8 @@ public class AuditsMetaDataProvider
|
|||||||
.withRecordLabelFormat("%s")
|
.withRecordLabelFormat("%s")
|
||||||
.withRecordLabelFields("id")
|
.withRecordLabelFields("id")
|
||||||
.withPrimaryKeyField("id")
|
.withPrimaryKeyField("id")
|
||||||
.withField(new QFieldMetaData("id", QFieldType.LONG))
|
.withField(new QFieldMetaData("id", QFieldType.INTEGER))
|
||||||
.withField(new QFieldMetaData("auditId", QFieldType.LONG).withPossibleValueSourceName(TABLE_NAME_AUDIT))
|
.withField(new QFieldMetaData("auditId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT))
|
||||||
.withField(new QFieldMetaData("message", QFieldType.STRING).withMaxLength(250).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS))
|
.withField(new QFieldMetaData("message", QFieldType.STRING).withMaxLength(250).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS))
|
||||||
.withField(new QFieldMetaData("fieldName", QFieldType.STRING).withMaxLength(100).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS))
|
.withField(new QFieldMetaData("fieldName", QFieldType.STRING).withMaxLength(100).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS))
|
||||||
.withField(new QFieldMetaData("oldValue", QFieldType.STRING).withMaxLength(250).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS))
|
.withField(new QFieldMetaData("oldValue", QFieldType.STRING).withMaxLength(250).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS))
|
||||||
|
@ -22,9 +22,6 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.dashboard.widgets;
|
package com.kingsrook.qqq.backend.core.model.dashboard.widgets;
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Model containing datastructure expected by frontend alert widget
|
** Model containing datastructure expected by frontend alert widget
|
||||||
**
|
**
|
||||||
@ -43,10 +40,8 @@ public class AlertData extends QWidgetData
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String html;
|
private String html;
|
||||||
private AlertType alertType;
|
private AlertType alertType;
|
||||||
private Boolean hideWidget = false;
|
|
||||||
private List<String> bulletList;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -144,66 +139,4 @@ public class AlertData extends QWidgetData
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for hideWidget
|
|
||||||
*******************************************************************************/
|
|
||||||
public boolean getHideWidget()
|
|
||||||
{
|
|
||||||
return (this.hideWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for hideWidget
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setHideWidget(boolean hideWidget)
|
|
||||||
{
|
|
||||||
this.hideWidget = hideWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for hideWidget
|
|
||||||
*******************************************************************************/
|
|
||||||
public AlertData withHideWidget(boolean hideWidget)
|
|
||||||
{
|
|
||||||
this.hideWidget = hideWidget;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for bulletList
|
|
||||||
*******************************************************************************/
|
|
||||||
public List<String> getBulletList()
|
|
||||||
{
|
|
||||||
return (this.bulletList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for bulletList
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setBulletList(List<String> bulletList)
|
|
||||||
{
|
|
||||||
this.bulletList = bulletList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for bulletList
|
|
||||||
*******************************************************************************/
|
|
||||||
public AlertData withBulletList(List<String> bulletList)
|
|
||||||
{
|
|
||||||
this.bulletList = bulletList;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,14 +39,9 @@ public class ChildRecordListData extends QWidgetData
|
|||||||
private QueryOutput queryOutput;
|
private QueryOutput queryOutput;
|
||||||
private QTableMetaData childTableMetaData;
|
private QTableMetaData childTableMetaData;
|
||||||
|
|
||||||
private String tableName;
|
|
||||||
private String tablePath;
|
private String tablePath;
|
||||||
private String viewAllLink;
|
private String viewAllLink;
|
||||||
private Integer totalRows;
|
private Integer totalRows;
|
||||||
private Boolean disableRowClick = false;
|
|
||||||
private Boolean allowRecordEdit = false;
|
|
||||||
private Boolean allowRecordDelete = false;
|
|
||||||
private Boolean isInProcess = false;
|
|
||||||
|
|
||||||
private boolean canAddChildRecord = false;
|
private boolean canAddChildRecord = false;
|
||||||
private Map<String, Serializable> defaultValuesForNewChildRecords;
|
private Map<String, Serializable> defaultValuesForNewChildRecords;
|
||||||
@ -357,173 +352,4 @@ public class ChildRecordListData extends QWidgetData
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for tableName
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getTableName()
|
|
||||||
{
|
|
||||||
return (this.tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for tableName
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setTableName(String tableName)
|
|
||||||
{
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for tableName
|
|
||||||
*******************************************************************************/
|
|
||||||
public ChildRecordListData withTableName(String tableName)
|
|
||||||
{
|
|
||||||
this.tableName = tableName;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for tablePath
|
|
||||||
*******************************************************************************/
|
|
||||||
public ChildRecordListData withTablePath(String tablePath)
|
|
||||||
{
|
|
||||||
this.tablePath = tablePath;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for disableRowClick
|
|
||||||
*******************************************************************************/
|
|
||||||
public Boolean getDisableRowClick()
|
|
||||||
{
|
|
||||||
return (this.disableRowClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for disableRowClick
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setDisableRowClick(Boolean disableRowClick)
|
|
||||||
{
|
|
||||||
this.disableRowClick = disableRowClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for disableRowClick
|
|
||||||
*******************************************************************************/
|
|
||||||
public ChildRecordListData withDisableRowClick(Boolean disableRowClick)
|
|
||||||
{
|
|
||||||
this.disableRowClick = disableRowClick;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for allowRecordEdit
|
|
||||||
*******************************************************************************/
|
|
||||||
public Boolean getAllowRecordEdit()
|
|
||||||
{
|
|
||||||
return (this.allowRecordEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for allowRecordEdit
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setAllowRecordEdit(Boolean allowRecordEdit)
|
|
||||||
{
|
|
||||||
this.allowRecordEdit = allowRecordEdit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for allowRecordEdit
|
|
||||||
*******************************************************************************/
|
|
||||||
public ChildRecordListData withAllowRecordEdit(Boolean allowRecordEdit)
|
|
||||||
{
|
|
||||||
this.allowRecordEdit = allowRecordEdit;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for allowRecordDelete
|
|
||||||
*******************************************************************************/
|
|
||||||
public Boolean getAllowRecordDelete()
|
|
||||||
{
|
|
||||||
return (this.allowRecordDelete);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for allowRecordDelete
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setAllowRecordDelete(Boolean allowRecordDelete)
|
|
||||||
{
|
|
||||||
this.allowRecordDelete = allowRecordDelete;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for allowRecordDelete
|
|
||||||
*******************************************************************************/
|
|
||||||
public ChildRecordListData withAllowRecordDelete(Boolean allowRecordDelete)
|
|
||||||
{
|
|
||||||
this.allowRecordDelete = allowRecordDelete;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for isInProcess
|
|
||||||
*******************************************************************************/
|
|
||||||
public Boolean getIsInProcess()
|
|
||||||
{
|
|
||||||
return (this.isInProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for isInProcess
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setIsInProcess(Boolean isInProcess)
|
|
||||||
{
|
|
||||||
this.isInProcess = isInProcess;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for isInProcess
|
|
||||||
*******************************************************************************/
|
|
||||||
public ChildRecordListData withIsInProcess(Boolean isInProcess)
|
|
||||||
{
|
|
||||||
this.isInProcess = isInProcess;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,24 +40,9 @@ public class CompositeWidgetData extends AbstractBlockWidgetData<CompositeWidget
|
|||||||
{
|
{
|
||||||
private List<AbstractBlockWidgetData<?, ?, ?, ?>> blocks = new ArrayList<>();
|
private List<AbstractBlockWidgetData<?, ?, ?, ?>> blocks = new ArrayList<>();
|
||||||
|
|
||||||
private ModalMode modalMode;
|
private Map<String, Serializable> styleOverrides = new HashMap<>();
|
||||||
|
|
||||||
|
private Layout layout;
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public enum ModalMode
|
|
||||||
{
|
|
||||||
MODAL
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Layout layout;
|
|
||||||
private Map<String, Serializable> styleOverrides = new HashMap<>();
|
|
||||||
private String overlayHtml;
|
|
||||||
private Map<String, Serializable> overlayStyleOverrides = new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -66,14 +51,12 @@ public class CompositeWidgetData extends AbstractBlockWidgetData<CompositeWidget
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public enum Layout
|
public enum Layout
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
// note, these are used in QQQ FMD CompositeWidget.tsx //
|
// note, these are used in QQQ FMD CompositeWidgetData.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
|
||||||
}
|
}
|
||||||
@ -235,122 +218,4 @@ public class CompositeWidgetData extends AbstractBlockWidgetData<CompositeWidget
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for overlayHtml
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getOverlayHtml()
|
|
||||||
{
|
|
||||||
return (this.overlayHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for overlayHtml
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setOverlayHtml(String overlayHtml)
|
|
||||||
{
|
|
||||||
this.overlayHtml = overlayHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for overlayHtml
|
|
||||||
*******************************************************************************/
|
|
||||||
public CompositeWidgetData withOverlayHtml(String overlayHtml)
|
|
||||||
{
|
|
||||||
this.overlayHtml = overlayHtml;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for overlayStyleOverrides
|
|
||||||
*******************************************************************************/
|
|
||||||
public Map<String, Serializable> getOverlayStyleOverrides()
|
|
||||||
{
|
|
||||||
return (this.overlayStyleOverrides);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for overlayStyleOverrides
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setOverlayStyleOverrides(Map<String, Serializable> overlayStyleOverrides)
|
|
||||||
{
|
|
||||||
this.overlayStyleOverrides = overlayStyleOverrides;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for overlayStyleOverrides
|
|
||||||
*******************************************************************************/
|
|
||||||
public CompositeWidgetData withOverlayStyleOverrides(Map<String, Serializable> overlayStyleOverrides)
|
|
||||||
{
|
|
||||||
this.overlayStyleOverrides = overlayStyleOverrides;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public CompositeWidgetData withOverlayStyleOverride(String key, Serializable value)
|
|
||||||
{
|
|
||||||
addOverlayStyleOverride(key, value);
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void addOverlayStyleOverride(String key, Serializable value)
|
|
||||||
{
|
|
||||||
if(this.overlayStyleOverrides == null)
|
|
||||||
{
|
|
||||||
this.overlayStyleOverrides = new HashMap<>();
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import java.util.Map;
|
|||||||
** Base class for the data returned by rendering a Widget.
|
** Base class for the data returned by rendering a Widget.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public abstract class QWidgetData implements Serializable
|
public abstract class QWidgetData
|
||||||
{
|
{
|
||||||
private String label;
|
private String label;
|
||||||
private String sublabel;
|
private String sublabel;
|
||||||
|
@ -24,7 +24,6 @@ package com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.CompositeWidgetData;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.QWidgetData;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.QWidgetData;
|
||||||
|
|
||||||
|
|
||||||
@ -52,11 +51,6 @@ 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;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -209,19 +203,6 @@ public abstract class AbstractBlockWidgetData<
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for tooltip
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T withTooltip(CompositeWidgetData data)
|
|
||||||
{
|
|
||||||
this.tooltip = new BlockTooltip(data);
|
|
||||||
return (T) (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -417,7 +398,6 @@ public abstract class AbstractBlockWidgetData<
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for blockId
|
** Getter for blockId
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -449,34 +429,4 @@ public abstract class AbstractBlockWidgetData<
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,14 @@
|
|||||||
package com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks;
|
package com.kingsrook.qqq.backend.core.model.dashboard.widgets.blocks;
|
||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.CompositeWidgetData;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** A tooltip used within a (widget) block.
|
** A tooltip used within a (widget) block.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class BlockTooltip
|
public class BlockTooltip
|
||||||
{
|
{
|
||||||
private CompositeWidgetData blockData;
|
private String title;
|
||||||
private String title;
|
private Placement placement = Placement.BOTTOM;
|
||||||
private Placement placement = Placement.BOTTOM;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -66,17 +62,6 @@ public class BlockTooltip
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Constructor
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public BlockTooltip(CompositeWidgetData blockData)
|
|
||||||
{
|
|
||||||
this.blockData = blockData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for title
|
** Getter for title
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -137,35 +122,4 @@ public class BlockTooltip
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for blockData
|
|
||||||
*******************************************************************************/
|
|
||||||
public CompositeWidgetData getBlockData()
|
|
||||||
{
|
|
||||||
return (this.blockData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for blockData
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setBlockData(CompositeWidgetData blockData)
|
|
||||||
{
|
|
||||||
this.blockData = blockData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for blockData
|
|
||||||
*******************************************************************************/
|
|
||||||
public BlockTooltip withBlockData(CompositeWidgetData blockData)
|
|
||||||
{
|
|
||||||
this.blockData = blockData;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,335 +30,4 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,218 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,325 +30,4 @@ 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,7 +23,6 @@ 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;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -33,9 +32,6 @@ public class TextValues implements BlockValuesInterface
|
|||||||
{
|
{
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
private QIcon startIcon;
|
|
||||||
private QIcon endIcon;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -88,66 +84,4 @@ 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,6 +22,9 @@
|
|||||||
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,6 +22,7 @@
|
|||||||
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;
|
||||||
@ -29,12 +30,14 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +51,8 @@ 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
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -82,7 +87,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 = ClassPathUtils.getClassesInPackage(packageName);
|
classesInPackage = getClassesInPackage(packageName);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -171,4 +176,51 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ 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;
|
||||||
@ -114,8 +113,6 @@ 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... //
|
||||||
@ -1488,35 +1485,4 @@ 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 withValues(Map<String, String> values)
|
public QAuthenticationMetaData withVales(Map<String, String> values)
|
||||||
{
|
{
|
||||||
this.values = values;
|
this.values = values;
|
||||||
return (this);
|
return (this);
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -41,7 +41,6 @@ public enum AdornmentType
|
|||||||
RENDER_HTML,
|
RENDER_HTML,
|
||||||
REVEAL,
|
REVEAL,
|
||||||
FILE_DOWNLOAD,
|
FILE_DOWNLOAD,
|
||||||
FILE_UPLOAD,
|
|
||||||
ERROR;
|
ERROR;
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// keep these values in sync with AdornmentType.ts in qqq-frontend-core //
|
// keep these values in sync with AdornmentType.ts in qqq-frontend-core //
|
||||||
@ -165,65 +164,4 @@ public enum AdornmentType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public static class FileUploadAdornment
|
|
||||||
{
|
|
||||||
public static String FORMAT = "format";
|
|
||||||
public static String WIDTH = "width";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public static FieldAdornment newFieldAdornment()
|
|
||||||
{
|
|
||||||
return (new FieldAdornment(AdornmentType.FILE_UPLOAD));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public static Pair<String, String> formatDragAndDrop()
|
|
||||||
{
|
|
||||||
return (Pair.of(FORMAT, "dragAndDrop"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public static Pair<String, String> formatButton()
|
|
||||||
{
|
|
||||||
return (Pair.of(FORMAT, "button"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public static Pair<String, String> widthFull()
|
|
||||||
{
|
|
||||||
return (Pair.of(WIDTH, "full"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public static Pair<String, String> widthHalf()
|
|
||||||
{
|
|
||||||
return (Pair.of(WIDTH, "half"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ public class FieldAdornment
|
|||||||
** Fluent setter for values
|
** Fluent setter for values
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public FieldAdornment withValue(Pair<String, ? extends Serializable> value)
|
public FieldAdornment withValue(Pair<String, Serializable> value)
|
||||||
{
|
{
|
||||||
return (withValue(value.getA(), value.getB()));
|
return (withValue(value.getA(), value.getB()));
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ 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;
|
||||||
@ -74,12 +73,10 @@ 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 String possibleValueSourceName;
|
private QQueryFilter possibleValueSourceFilter;
|
||||||
private QQueryFilter possibleValueSourceFilter;
|
|
||||||
private QPossibleValueSource inlinePossibleValueSource;
|
|
||||||
|
|
||||||
private Integer maxLength;
|
private Integer maxLength;
|
||||||
private Set<FieldBehavior<?>> behaviors;
|
private Set<FieldBehavior<?>> behaviors;
|
||||||
@ -1061,35 +1058,4 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import java.time.Instant;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -101,16 +100,6 @@ public enum QFieldType
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
public String getMixedCaseLabel()
|
|
||||||
{
|
|
||||||
return StringUtils.allCapsToMixedCase(name());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -26,7 +26,6 @@ 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;
|
||||||
@ -46,7 +45,7 @@ public class AppTreeNode
|
|||||||
private String label;
|
private String label;
|
||||||
private List<AppTreeNode> children;
|
private List<AppTreeNode> children;
|
||||||
|
|
||||||
private QIcon icon;
|
private String iconName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -83,7 +82,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.icon = appChildMetaData.getIcon();
|
this.iconName = appChildMetaData.getIcon().getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,18 +138,7 @@ public class AppTreeNode
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return (icon == null ? null : icon.getName());
|
return iconName;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for icon
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public QIcon getIcon()
|
|
||||||
{
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ 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;
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ public class QFrontendAppMetaData
|
|||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
private String label;
|
private String label;
|
||||||
private QIcon icon;
|
private String iconName;
|
||||||
|
|
||||||
private List<String> widgets = new ArrayList<>();
|
private List<String> widgets = new ArrayList<>();
|
||||||
private List<AppTreeNode> children = new ArrayList<>();
|
private List<AppTreeNode> children = new ArrayList<>();
|
||||||
@ -57,7 +56,6 @@ public class QFrontendAppMetaData
|
|||||||
private Map<String, QSupplementalAppMetaData> supplementalAppMetaData;
|
private Map<String, QSupplementalAppMetaData> supplementalAppMetaData;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -65,7 +63,11 @@ 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))
|
||||||
@ -79,10 +81,6 @@ 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();
|
||||||
@ -176,7 +174,18 @@ public class QFrontendAppMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return (icon == null ? null : icon.getName());
|
return iconName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for iconName
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setIconName(String iconName)
|
||||||
|
{
|
||||||
|
this.iconName = iconName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -226,15 +235,4 @@ public class QFrontendAppMetaData
|
|||||||
{
|
{
|
||||||
return supplementalAppMetaData;
|
return supplementalAppMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for icon
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public QIcon getIcon()
|
|
||||||
{
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
|||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@JsonInclude(Include.NON_NULL)
|
@JsonInclude(Include.NON_NULL)
|
||||||
public class QFrontendFieldMetaData implements Serializable
|
public class QFrontendFieldMetaData
|
||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
private String label;
|
private String label;
|
||||||
@ -57,7 +56,6 @@ public class QFrontendFieldMetaData implements Serializable
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -83,7 +81,6 @@ public class QFrontendFieldMetaData implements Serializable
|
|||||||
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()))
|
||||||
{
|
{
|
||||||
@ -221,17 +218,6 @@ public class QFrontendFieldMetaData implements Serializable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for inlinePossibleValueSource
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public QPossibleValueSource getInlinePossibleValueSource()
|
|
||||||
{
|
|
||||||
return inlinePossibleValueSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for fieldBehaviors
|
** Getter for fieldBehaviors
|
||||||
**
|
**
|
||||||
|
@ -29,10 +29,8 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
@ -49,10 +47,9 @@ public class QFrontendProcessMetaData
|
|||||||
private String tableName;
|
private String tableName;
|
||||||
private boolean isHidden;
|
private boolean isHidden;
|
||||||
|
|
||||||
private QIcon icon;
|
private String iconName;
|
||||||
|
|
||||||
private List<QFrontendStepMetaData> frontendSteps;
|
private List<QFrontendStepMetaData> frontendSteps;
|
||||||
private String stepFlow;
|
|
||||||
|
|
||||||
private boolean hasPermission;
|
private boolean hasPermission;
|
||||||
|
|
||||||
@ -71,27 +68,15 @@ 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 = switch(processMetaData.getStepFlow())
|
this.frontendSteps = processMetaData.getStepList().stream()
|
||||||
{
|
.filter(QFrontendStepMetaData.class::isInstance)
|
||||||
case LINEAR -> processMetaData.getStepList().stream()
|
.map(QFrontendStepMetaData.class::cast)
|
||||||
.filter(QFrontendStepMetaData.class::isInstance)
|
.collect(Collectors.toList());
|
||||||
.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
|
||||||
{
|
{
|
||||||
@ -99,7 +84,10 @@ public class QFrontendProcessMetaData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.icon = processMetaData.getIcon();
|
if(processMetaData.getIcon() != null)
|
||||||
|
{
|
||||||
|
this.iconName = processMetaData.getIcon().getName();
|
||||||
|
}
|
||||||
|
|
||||||
hasPermission = PermissionsHelper.hasProcessPermission(actionInput, name);
|
hasPermission = PermissionsHelper.hasProcessPermission(actionInput, name);
|
||||||
}
|
}
|
||||||
@ -178,7 +166,7 @@ public class QFrontendProcessMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return icon == null ? null : icon.getName();
|
return iconName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -192,25 +180,4 @@ 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.LinkedHashSet;
|
import java.util.HashSet;
|
||||||
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,7 +40,6 @@ 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;
|
||||||
@ -62,7 +61,7 @@ public class QFrontendTableMetaData
|
|||||||
private String label;
|
private String label;
|
||||||
private boolean isHidden;
|
private boolean isHidden;
|
||||||
private String primaryKeyField;
|
private String primaryKeyField;
|
||||||
private QIcon icon;
|
private String iconName;
|
||||||
|
|
||||||
private Map<String, QFrontendFieldMetaData> fields;
|
private Map<String, QFrontendFieldMetaData> fields;
|
||||||
private List<QFieldSection> sections;
|
private List<QFieldSection> sections;
|
||||||
@ -157,7 +156,10 @@ public class QFrontendTableMetaData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.icon = tableMetaData.getIcon();
|
if(tableMetaData.getIcon() != null)
|
||||||
|
{
|
||||||
|
this.iconName = tableMetaData.getIcon().getName();
|
||||||
|
}
|
||||||
|
|
||||||
setCapabilities(backendForTable, tableMetaData);
|
setCapabilities(backendForTable, tableMetaData);
|
||||||
|
|
||||||
@ -183,7 +185,7 @@ public class QFrontendTableMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private void setCapabilities(QBackendMetaData backend, QTableMetaData table)
|
private void setCapabilities(QBackendMetaData backend, QTableMetaData table)
|
||||||
{
|
{
|
||||||
Set<Capability> enabledCapabilities = new LinkedHashSet<>();
|
Set<Capability> enabledCapabilities = new HashSet<>();
|
||||||
for(Capability capability : Capability.values())
|
for(Capability capability : Capability.values())
|
||||||
{
|
{
|
||||||
if(table.isCapabilityEnabled(backend, capability))
|
if(table.isCapabilityEnabled(backend, capability))
|
||||||
@ -273,7 +275,7 @@ public class QFrontendTableMetaData
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public String getIconName()
|
public String getIconName()
|
||||||
{
|
{
|
||||||
return (icon == null ? null : icon.getName());
|
return iconName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -395,16 +397,4 @@ public class QFrontendTableMetaData
|
|||||||
{
|
{
|
||||||
return helpContents;
|
return helpContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for icon
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public QIcon getIcon()
|
|
||||||
{
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.possiblevalues;
|
|
||||||
|
|
||||||
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.CriteriaMissingInputValueBehavior;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.FilterUseCase;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** FilterUseCase implementation for the ways that possible value searches
|
|
||||||
** are performed, and where we want to have different behaviors for criteria
|
|
||||||
** that are missing an input value. That is, either for a:
|
|
||||||
**
|
|
||||||
** - FORM - e.g., creating a new record, or in a process - where we want a
|
|
||||||
** missing filter value to basically block you from selecting a value in the
|
|
||||||
** PVS field - e.g., you must enter some other foreign-key value before choosing
|
|
||||||
** from this possible value - at least that's the use-case we know of now.
|
|
||||||
**
|
|
||||||
** - FILTER - e.g., a query screen - where there isn't really quite the same
|
|
||||||
** scenario of choosing that foreign-key value first - so, such a PVS should
|
|
||||||
** list all its values (e.g., a criteria missing an input value should be
|
|
||||||
** removed from the filter).
|
|
||||||
*******************************************************************************/
|
|
||||||
public enum PossibleValueSearchFilterUseCase implements FilterUseCase
|
|
||||||
{
|
|
||||||
FORM(CriteriaMissingInputValueBehavior.MAKE_NO_MATCHES),
|
|
||||||
FILTER(CriteriaMissingInputValueBehavior.REMOVE_FROM_FILTER);
|
|
||||||
|
|
||||||
|
|
||||||
private final CriteriaMissingInputValueBehavior defaultCriteriaMissingInputValueBehavior;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
PossibleValueSearchFilterUseCase(CriteriaMissingInputValueBehavior defaultCriteriaMissingInputValueBehavior)
|
|
||||||
{
|
|
||||||
this.defaultCriteriaMissingInputValueBehavior = defaultCriteriaMissingInputValueBehavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for defaultCriteriaMissingInputValueBehavior
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public CriteriaMissingInputValueBehavior getDefaultCriteriaMissingInputValueBehavior()
|
|
||||||
{
|
|
||||||
return defaultCriteriaMissingInputValueBehavior;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
}
|
|
@ -29,9 +29,6 @@ public enum QComponentType
|
|||||||
{
|
{
|
||||||
HELP_TEXT,
|
HELP_TEXT,
|
||||||
BULK_EDIT_FORM,
|
BULK_EDIT_FORM,
|
||||||
BULK_LOAD_FILE_MAPPING_FORM,
|
|
||||||
BULK_LOAD_VALUE_MAPPING_FORM,
|
|
||||||
BULK_LOAD_PROFILE_FORM,
|
|
||||||
VALIDATION_REVIEW_SCREEN,
|
VALIDATION_REVIEW_SCREEN,
|
||||||
EDIT_FORM,
|
EDIT_FORM,
|
||||||
VIEW_FORM,
|
VIEW_FORM,
|
||||||
|
@ -47,9 +47,6 @@ 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 String backStepName;
|
|
||||||
|
|
||||||
private List<QHelpContent> helpContents;
|
private List<QHelpContent> helpContents;
|
||||||
|
|
||||||
|
|
||||||
@ -406,66 +403,4 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for backStepName
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getBackStepName()
|
|
||||||
{
|
|
||||||
return (this.backStepName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for backStepName
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setBackStepName(String backStepName)
|
|
||||||
{
|
|
||||||
this.backStepName = backStepName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for backStepName
|
|
||||||
*******************************************************************************/
|
|
||||||
public QFrontendStepMetaData withBackStepName(String backStepName)
|
|
||||||
{
|
|
||||||
this.backStepName = backStepName;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ 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
|
||||||
|
|
||||||
@ -214,10 +213,11 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*******************************************************************************
|
||||||
|
** add a step to the stepList and map
|
||||||
**
|
**
|
||||||
***************************************************************************/
|
*******************************************************************************/
|
||||||
public QProcessMetaData withStep(QStepMetaData step)
|
public QProcessMetaData addStep(QStepMetaData step)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if(this.stepList != null)
|
if(this.stepList != null)
|
||||||
@ -231,23 +231,11 @@ 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 withStep(int index, QStepMetaData step)
|
public QProcessMetaData addStep(int index, QStepMetaData step)
|
||||||
{
|
{
|
||||||
if(this.stepList == null)
|
if(this.stepList == null)
|
||||||
{
|
{
|
||||||
@ -272,23 +260,11 @@ 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 withOptionalStep(QStepMetaData step)
|
public QProcessMetaData addOptionalStep(QStepMetaData step)
|
||||||
{
|
{
|
||||||
if(this.steps == null)
|
if(this.steps == null)
|
||||||
{
|
{
|
||||||
@ -307,18 +283,6 @@ 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
|
||||||
**
|
**
|
||||||
@ -335,26 +299,7 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public QStepMetaData getStep(String stepName)
|
public QStepMetaData getStep(String stepName)
|
||||||
{
|
{
|
||||||
if(steps.containsKey(stepName))
|
return (steps.get(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -835,35 +780,4 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,188 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -32,13 +32,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Meta-data definition of a source of data for a report (e.g., a table and query
|
** Meta-data definition of a source of data for a report (e.g., a table and query
|
||||||
** filter or custom-code reference).
|
** filter or custom-code reference).
|
||||||
**
|
|
||||||
** Runs in 3 modes:
|
|
||||||
**
|
|
||||||
** - If a customRecordSource is specified, then that code is executed to get the records.
|
|
||||||
** - else, if a sourceTable is specified, then the corresponding queryFilter
|
|
||||||
** (optionally along with queryJoins and queryInputCustomizer) is used.
|
|
||||||
** - else a staticDataSupplier is used.
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class QReportDataSource
|
public class QReportDataSource
|
||||||
{
|
{
|
||||||
@ -51,7 +44,6 @@ public class QReportDataSource
|
|||||||
|
|
||||||
private QCodeReference queryInputCustomizer;
|
private QCodeReference queryInputCustomizer;
|
||||||
private QCodeReference staticDataSupplier;
|
private QCodeReference staticDataSupplier;
|
||||||
private QCodeReference customRecordSource;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -273,35 +265,4 @@ public class QReportDataSource
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for customRecordSource
|
|
||||||
*******************************************************************************/
|
|
||||||
public QCodeReference getCustomRecordSource()
|
|
||||||
{
|
|
||||||
return (this.customRecordSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for customRecordSource
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setCustomRecordSource(QCodeReference customRecordSource)
|
|
||||||
{
|
|
||||||
this.customRecordSource = customRecordSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for customRecordSource
|
|
||||||
*******************************************************************************/
|
|
||||||
public QReportDataSource withCustomRecordSource(QCodeReference customRecordSource)
|
|
||||||
{
|
|
||||||
this.customRecordSource = customRecordSource;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.metadata.MetaDataProducerInterface;
|
import com.kingsrook.qqq.backend.core.model.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;
|
||||||
|
@ -1,285 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.savedbulkloadprofiles;
|
|
||||||
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QField;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.DynamicDefaultValueBehavior;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.ValueTooLongBehavior;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.TablesPossibleValueSourceMetaDataProvider;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Entity bean for the savedBulkLoadProfile table
|
|
||||||
*******************************************************************************/
|
|
||||||
public class SavedBulkLoadProfile extends QRecordEntity
|
|
||||||
{
|
|
||||||
public static final String TABLE_NAME = "savedBulkLoadProfile";
|
|
||||||
|
|
||||||
@QField(isEditable = false)
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
@QField(isEditable = false)
|
|
||||||
private Instant createDate;
|
|
||||||
|
|
||||||
@QField(isEditable = false)
|
|
||||||
private Instant modifyDate;
|
|
||||||
|
|
||||||
@QField(isRequired = true, maxLength = 250, valueTooLongBehavior = ValueTooLongBehavior.TRUNCATE_ELLIPSIS, label = "Profile Name")
|
|
||||||
private String label;
|
|
||||||
|
|
||||||
@QField(possibleValueSourceName = TablesPossibleValueSourceMetaDataProvider.NAME, maxLength = 250, valueTooLongBehavior = ValueTooLongBehavior.ERROR, label = "Table", isRequired = true)
|
|
||||||
private String tableName;
|
|
||||||
|
|
||||||
@QField(maxLength = 250, valueTooLongBehavior = ValueTooLongBehavior.ERROR, dynamicDefaultValueBehavior = DynamicDefaultValueBehavior.USER_ID, label = "Owner")
|
|
||||||
private String userId;
|
|
||||||
|
|
||||||
@QField(label = "Mapping JSON")
|
|
||||||
private String mappingJson;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Constructor
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SavedBulkLoadProfile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Constructor
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SavedBulkLoadProfile(QRecord qRecord) throws QException
|
|
||||||
{
|
|
||||||
populateFromQRecord(qRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for id
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public Integer getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for id
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setId(Integer id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for createDate
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public Instant getCreateDate()
|
|
||||||
{
|
|
||||||
return createDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for createDate
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setCreateDate(Instant createDate)
|
|
||||||
{
|
|
||||||
this.createDate = createDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for modifyDate
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public Instant getModifyDate()
|
|
||||||
{
|
|
||||||
return modifyDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for modifyDate
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setModifyDate(Instant modifyDate)
|
|
||||||
{
|
|
||||||
this.modifyDate = modifyDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for label
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getLabel()
|
|
||||||
{
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for label
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setLabel(String label)
|
|
||||||
{
|
|
||||||
this.label = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for label
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SavedBulkLoadProfile withLabel(String label)
|
|
||||||
{
|
|
||||||
this.label = label;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for tableName
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getTableName()
|
|
||||||
{
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for tableName
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setTableName(String tableName)
|
|
||||||
{
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for tableName
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SavedBulkLoadProfile withTableName(String tableName)
|
|
||||||
{
|
|
||||||
this.tableName = tableName;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for userId
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getUserId()
|
|
||||||
{
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for userId
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setUserId(String userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for userId
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SavedBulkLoadProfile withUserId(String userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for mappingJson
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getMappingJson()
|
|
||||||
{
|
|
||||||
return (this.mappingJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for mappingJson
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setMappingJson(String mappingJson)
|
|
||||||
{
|
|
||||||
this.mappingJson = mappingJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for mappingJson
|
|
||||||
*******************************************************************************/
|
|
||||||
public SavedBulkLoadProfile withMappingJson(String mappingJson)
|
|
||||||
{
|
|
||||||
this.mappingJson = mappingJson;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.savedbulkloadprofiles;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
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.audits.AuditLevel;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.audits.QAuditRules;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareScopePossibleValueMetaDataProducer;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareableAudienceType;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareableTableMetaData;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedbulkloadprofiles.DeleteSavedBulkLoadProfileProcess;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedbulkloadprofiles.QuerySavedBulkLoadProfileProcess;
|
|
||||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedbulkloadprofiles.StoreSavedBulkLoadProfileProcess;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public class SavedBulkLoadProfileMetaDataProvider
|
|
||||||
{
|
|
||||||
public static final String SHARED_SAVED_BULK_LOAD_PROFILE_JOIN_SAVED_BULK_LOAD_PROFILE = "sharedSavedBulkLoadProfileJoinSavedBulkLoadProfile";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public void defineAll(QInstance instance, String recordTablesBackendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
|
||||||
{
|
|
||||||
instance.addTable(defineSavedBulkLoadProfileTable(recordTablesBackendName, backendDetailEnricher));
|
|
||||||
instance.addPossibleValueSource(QPossibleValueSource.newForTable(SavedBulkLoadProfile.TABLE_NAME));
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
|
||||||
// todo - param to enable sharing? //
|
|
||||||
/////////////////////////////////////
|
|
||||||
instance.addTable(defineSharedSavedBulkLoadProfileTable(recordTablesBackendName, backendDetailEnricher));
|
|
||||||
instance.addJoin(defineSharedSavedBulkLoadProfileJoinSavedBulkLoadProfile());
|
|
||||||
if(instance.getPossibleValueSource(ShareScopePossibleValueMetaDataProducer.NAME) == null)
|
|
||||||
{
|
|
||||||
instance.addPossibleValueSource(new ShareScopePossibleValueMetaDataProducer().produce(new QInstance()));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// processes for working with 'em //
|
|
||||||
////////////////////////////////////
|
|
||||||
instance.add(StoreSavedBulkLoadProfileProcess.getProcessMetaData());
|
|
||||||
instance.add(QuerySavedBulkLoadProfileProcess.getProcessMetaData());
|
|
||||||
instance.add(DeleteSavedBulkLoadProfileProcess.getProcessMetaData());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
private QJoinMetaData defineSharedSavedBulkLoadProfileJoinSavedBulkLoadProfile()
|
|
||||||
{
|
|
||||||
return (new QJoinMetaData()
|
|
||||||
.withName(SHARED_SAVED_BULK_LOAD_PROFILE_JOIN_SAVED_BULK_LOAD_PROFILE)
|
|
||||||
.withLeftTable(SharedSavedBulkLoadProfile.TABLE_NAME)
|
|
||||||
.withRightTable(SavedBulkLoadProfile.TABLE_NAME)
|
|
||||||
.withType(JoinType.MANY_TO_ONE)
|
|
||||||
.withJoinOn(new JoinOn("savedBulkLoadProfileId", "id")));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public QTableMetaData defineSavedBulkLoadProfileTable(String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
|
||||||
{
|
|
||||||
QTableMetaData table = new QTableMetaData()
|
|
||||||
.withName(SavedBulkLoadProfile.TABLE_NAME)
|
|
||||||
.withLabel("Bulk Load Profile")
|
|
||||||
.withIcon(new QIcon().withName("drive_folder_upload"))
|
|
||||||
.withRecordLabelFormat("%s")
|
|
||||||
.withRecordLabelFields("label")
|
|
||||||
.withBackendName(backendName)
|
|
||||||
.withPrimaryKeyField("id")
|
|
||||||
.withFieldsFromEntity(SavedBulkLoadProfile.class)
|
|
||||||
.withAuditRules(new QAuditRules().withAuditLevel(AuditLevel.FIELD))
|
|
||||||
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "label", "tableName")))
|
|
||||||
.withSection(new QFieldSection("data", new QIcon().withName("text_snippet"), Tier.T2, List.of("mappingJson")).withIsHidden(true))
|
|
||||||
.withSection(new QFieldSection("hidden", new QIcon().withName("text_snippet"), Tier.T2, List.of("userId")).withIsHidden(true))
|
|
||||||
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate")));
|
|
||||||
|
|
||||||
// todo - want one of these?
|
|
||||||
// table.getField("queryFilterJson").withBehavior(SavedReportJsonFieldDisplayValueFormatter.getInstance());
|
|
||||||
|
|
||||||
table.withShareableTableMetaData(new ShareableTableMetaData()
|
|
||||||
.withSharedRecordTableName(SharedSavedBulkLoadProfile.TABLE_NAME)
|
|
||||||
.withAssetIdFieldName("savedBulkLoadProfileId")
|
|
||||||
.withScopeFieldName("scope")
|
|
||||||
.withThisTableOwnerIdFieldName("userId")
|
|
||||||
.withAudienceType(new ShareableAudienceType().withName("user").withFieldName("userId")));
|
|
||||||
|
|
||||||
if(backendDetailEnricher != null)
|
|
||||||
{
|
|
||||||
backendDetailEnricher.accept(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (table);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public QTableMetaData defineSharedSavedBulkLoadProfileTable(String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
|
||||||
{
|
|
||||||
QTableMetaData table = new QTableMetaData()
|
|
||||||
.withName(SharedSavedBulkLoadProfile.TABLE_NAME)
|
|
||||||
.withLabel("Shared Bulk Load Profile")
|
|
||||||
.withIcon(new QIcon().withName("share"))
|
|
||||||
.withRecordLabelFormat("%s")
|
|
||||||
.withRecordLabelFields("savedBulkLoadProfileId")
|
|
||||||
.withBackendName(backendName)
|
|
||||||
.withUniqueKey(new UniqueKey("savedBulkLoadProfileId", "userId"))
|
|
||||||
.withPrimaryKeyField("id")
|
|
||||||
.withFieldsFromEntity(SharedSavedBulkLoadProfile.class)
|
|
||||||
// todo - security key
|
|
||||||
.withAuditRules(new QAuditRules().withAuditLevel(AuditLevel.FIELD))
|
|
||||||
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "savedBulkLoadProfileId", "userId")))
|
|
||||||
.withSection(new QFieldSection("data", new QIcon().withName("text_snippet"), Tier.T2, List.of("scope")))
|
|
||||||
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate")));
|
|
||||||
|
|
||||||
if(backendDetailEnricher != null)
|
|
||||||
{
|
|
||||||
backendDetailEnricher.accept(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (table);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,268 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.savedbulkloadprofiles;
|
|
||||||
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QField;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareScopePossibleValueMetaDataProducer;
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Entity bean for the shared saved bulk load profile table
|
|
||||||
*******************************************************************************/
|
|
||||||
public class SharedSavedBulkLoadProfile extends QRecordEntity
|
|
||||||
{
|
|
||||||
public static final String TABLE_NAME = "sharedSavedBulkLoadProfile";
|
|
||||||
|
|
||||||
@QField(isEditable = false)
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
@QField(isEditable = false)
|
|
||||||
private Instant createDate;
|
|
||||||
|
|
||||||
@QField(isEditable = false)
|
|
||||||
private Instant modifyDate;
|
|
||||||
|
|
||||||
@QField(possibleValueSourceName = SavedBulkLoadProfile.TABLE_NAME, label = "Bulk Load Profile")
|
|
||||||
private Integer savedBulkLoadProfileId;
|
|
||||||
|
|
||||||
@QField(label = "User")
|
|
||||||
private String userId;
|
|
||||||
|
|
||||||
@QField(possibleValueSourceName = ShareScopePossibleValueMetaDataProducer.NAME)
|
|
||||||
private String scope;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Constructor
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Constructor
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile(QRecord qRecord) throws QException
|
|
||||||
{
|
|
||||||
populateFromQRecord(qRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for id
|
|
||||||
*******************************************************************************/
|
|
||||||
public Integer getId()
|
|
||||||
{
|
|
||||||
return (this.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for id
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setId(Integer id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for id
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile withId(Integer id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for createDate
|
|
||||||
*******************************************************************************/
|
|
||||||
public Instant getCreateDate()
|
|
||||||
{
|
|
||||||
return (this.createDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for createDate
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setCreateDate(Instant createDate)
|
|
||||||
{
|
|
||||||
this.createDate = createDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for createDate
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile withCreateDate(Instant createDate)
|
|
||||||
{
|
|
||||||
this.createDate = createDate;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for modifyDate
|
|
||||||
*******************************************************************************/
|
|
||||||
public Instant getModifyDate()
|
|
||||||
{
|
|
||||||
return (this.modifyDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for modifyDate
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setModifyDate(Instant modifyDate)
|
|
||||||
{
|
|
||||||
this.modifyDate = modifyDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for modifyDate
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile withModifyDate(Instant modifyDate)
|
|
||||||
{
|
|
||||||
this.modifyDate = modifyDate;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for userId
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getUserId()
|
|
||||||
{
|
|
||||||
return (this.userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for userId
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setUserId(String userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for userId
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile withUserId(String userId)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for scope
|
|
||||||
*******************************************************************************/
|
|
||||||
public String getScope()
|
|
||||||
{
|
|
||||||
return (this.scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for scope
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setScope(String scope)
|
|
||||||
{
|
|
||||||
this.scope = scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for scope
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile withScope(String scope)
|
|
||||||
{
|
|
||||||
this.scope = scope;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Getter for savedBulkLoadProfileId
|
|
||||||
*******************************************************************************/
|
|
||||||
public Integer getSavedBulkLoadProfileId()
|
|
||||||
{
|
|
||||||
return (this.savedBulkLoadProfileId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Setter for savedBulkLoadProfileId
|
|
||||||
*******************************************************************************/
|
|
||||||
public void setSavedBulkLoadProfileId(Integer savedBulkLoadProfileId)
|
|
||||||
{
|
|
||||||
this.savedBulkLoadProfileId = savedBulkLoadProfileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
** Fluent setter for savedBulkLoadProfileId
|
|
||||||
*******************************************************************************/
|
|
||||||
public SharedSavedBulkLoadProfile withSavedBulkLoadProfileId(Integer savedBulkLoadProfileId)
|
|
||||||
{
|
|
||||||
this.savedBulkLoadProfileId = savedBulkLoadProfileId;
|
|
||||||
return (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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());
|
||||||
|
@ -48,7 +48,7 @@ public class QSession implements Serializable, Cloneable
|
|||||||
private QUser user;
|
private QUser user;
|
||||||
private String uuid;
|
private String uuid;
|
||||||
|
|
||||||
private Set<String> permissions;
|
private Set<String> permissions;
|
||||||
|
|
||||||
private Map<String, List<Serializable>> securityKeyValues;
|
private Map<String, List<Serializable>> securityKeyValues;
|
||||||
private Map<String, Serializable> backendVariants;
|
private Map<String, Serializable> backendVariants;
|
||||||
@ -360,38 +360,12 @@ public class QSession implements Serializable, Cloneable
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Serializable> values = securityKeyValues.get(keyName);
|
List<Serializable> values = securityKeyValues.get(keyName);
|
||||||
|
Serializable valueAsType = ValueUtils.getValueAsFieldType(fieldType, value);
|
||||||
Serializable valueAsType;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
valueAsType = ValueUtils.getValueAsFieldType(fieldType, value);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// an exception in getValueAsFieldType would indicate, e.g., a non-number string trying to come back as integer. //
|
|
||||||
// so - assume that any such mismatch means the value isn't in the session. //
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Serializable keyValue : values)
|
for(Serializable keyValue : values)
|
||||||
{
|
{
|
||||||
Serializable keyValueAsType = null;
|
Serializable keyValueAsType = ValueUtils.getValueAsFieldType(fieldType, keyValue);
|
||||||
try
|
if(keyValueAsType.equals(valueAsType))
|
||||||
{
|
|
||||||
keyValueAsType = ValueUtils.getValueAsFieldType(fieldType, keyValue);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// an exception in getValueAsFieldType would indicate, e.g., a non-number string trying to come back as integer. //
|
|
||||||
// so - assume that any such mismatch means this key isn't a match.
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valueAsType.equals(keyValueAsType))
|
|
||||||
{
|
{
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@ -587,7 +561,6 @@ public class QSession implements Serializable, Cloneable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for valuesForFrontend
|
** Getter for valuesForFrontend
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -618,7 +591,6 @@ public class QSession implements Serializable, Cloneable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Fluent setter for a single valuesForFrontend
|
** Fluent setter for a single valuesForFrontend
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -632,4 +604,5 @@ public class QSession implements Serializable, Cloneable
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,10 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// allow customizer to do custom things here, if so desired //
|
// allow customizer to do custom things here, if so desired //
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
finalCustomizeSession(qInstance, qSession);
|
if(getCustomizer() != null)
|
||||||
|
{
|
||||||
|
getCustomizer().finalCustomizeSession(qInstance, qSession);
|
||||||
|
}
|
||||||
|
|
||||||
return (qSession);
|
return (qSession);
|
||||||
}
|
}
|
||||||
@ -308,7 +311,10 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// allow customizer to do custom things here, if so desired //
|
// allow customizer to do custom things here, if so desired //
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
finalCustomizeSession(qInstance, qSession);
|
if(getCustomizer() != null)
|
||||||
|
{
|
||||||
|
getCustomizer().finalCustomizeSession(qInstance, qSession);
|
||||||
|
}
|
||||||
|
|
||||||
return (qSession);
|
return (qSession);
|
||||||
}
|
}
|
||||||
@ -354,23 +360,6 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
**
|
|
||||||
***************************************************************************/
|
|
||||||
private void finalCustomizeSession(QInstance qInstance, QSession qSession)
|
|
||||||
{
|
|
||||||
if(getCustomizer() != null)
|
|
||||||
{
|
|
||||||
QContext.withTemporaryContext(QContext.capture(), () ->
|
|
||||||
{
|
|
||||||
QContext.setQSession(getChickenAndEggSession());
|
|
||||||
getCustomizer().finalCustomizeSession(qInstance, qSession);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Insert a session as a new record into userSession table
|
** Insert a session as a new record into userSession table
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user