Content-Length: 12158 | pFad | http://github.com/lowcoder-org/lowcoder/pull/1443.diff
thub.com
diff --git a/client/packages/lowcoder/src/comps/queries/queryComp.tsx b/client/packages/lowcoder/src/comps/queries/queryComp.tsx
index 1937bf289..e90bf8d19 100644
--- a/client/packages/lowcoder/src/comps/queries/queryComp.tsx
+++ b/client/packages/lowcoder/src/comps/queries/queryComp.tsx
@@ -97,10 +97,25 @@ interface AfterExecuteQueryAction {
result: QueryResult;
}
-const TriggerTypeOptions = [
+const CommonTriggerOptions = [
+ { label: trans("query.triggerTypeInputChange"), value: "onInputChange"},
+ { label: trans("query.triggerTypeQueryExec"), value: "onQueryExecution"},
+ { label: trans("query.triggerTypeTimeout"), value: "onTimeout"},
+]
+
+export const TriggerTypeOptions = [
+ { label: trans("query.triggerTypePageLoad"), value: "onPageLoad"},
+ ...CommonTriggerOptions,
{ label: trans("query.triggerTypeAuto"), value: "automatic" },
{ label: trans("query.triggerTypeManual"), value: "manual" },
] as const;
+
+export const JSTriggerTypeOptions = [
+ ...CommonTriggerOptions,
+ { label: trans("query.triggerTypePageLoad"), value: "automatic" },
+ { label: trans("query.triggerTypeManual"), value: "manual" },
+];
+
export type TriggerType = ValueFromOption;
const EventOptions = [
@@ -151,6 +166,13 @@ const childrenMap = {
},
}),
cancelPrevious: withDefault(BoolPureControl, false),
+ // use only for onQueryExecution trigger
+ depQueryName: SimpleNameComp,
+ // use only for onTimeout trigger, triggers query after x time passed on page load
+ delayTime: millisecondsControl({
+ left: 0,
+ defaultValue: 5 * 1000,
+ })
};
let QueryCompTmp = withTypeAndChildren>(
@@ -174,6 +196,7 @@ export type QueryChildrenType = InstanceType extends MultiB
? X
: never;
+let blockInputChangeQueries = true;
/**
* Logic to automatically trigger execution
*/
@@ -222,11 +245,17 @@ QueryCompTmp = class extends QueryCompTmp {
const isJsQuery = this.children.compType.getView() === "js";
const notExecuted = this.children.lastQueryStartTime.getView() === -1;
const isAutomatic = getTriggerType(this) === "automatic";
+ const isPageLoadTrigger = getTriggerType(this) === "onPageLoad";
+ const isInputChangeTrigger = getTriggerType(this) === "onInputChange";
if (
- action.type === CompActionTypes.UPDATE_NODES_V2 &&
- isAutomatic &&
- (!isJsQuery || (isJsQuery && notExecuted)) // query which has deps can be executed on page load(first time)
+ action.type === CompActionTypes.UPDATE_NODES_V2
+ && (
+ isAutomatic
+ || isInputChangeTrigger
+ || (isPageLoadTrigger && notExecuted)
+ )
+ // && (!isJsQuery || (isJsQuery && notExecuted)) // query which has deps can be executed on page load(first time)
) {
const next = super.reduce(action);
const depends = this.children.comp.node()?.dependValues();
@@ -250,6 +279,18 @@ QueryCompTmp = class extends QueryCompTmp {
const dependsChanged = !_.isEqual(preDepends, depends);
const dslNotChanged = _.isEqual(preDsl, dsl);
+ if(isInputChangeTrigger && blockInputChangeQueries && dependsChanged) {
+ // block executing input change queries initially on page refresh
+ setTimeout(() => {
+ blockInputChangeQueries = false;
+ }, 500)
+
+ return setFieldsNoTypeCheck(next, {
+ [lastDependsKey]: depends,
+ [lastDslKey]: dsl,
+ });
+ }
+
// If the dsl has not changed, but the dependent node value has changed, then trigger the query execution
// FIXME, this should be changed to a reference judgement, but for unknown reasons if the reference is modified once, it will change twice.
if (dependsChanged) {
@@ -277,7 +318,10 @@ function QueryView(props: QueryViewProps) {
useEffect(() => {
// Automatically load when page load
if (
- getTriggerType(comp) === "automatic" &&
+ (
+ getTriggerType(comp) === "automatic"
+ || getTriggerType(comp) === "onPageLoad"
+ ) &&
(comp as any).isDepReady &&
!comp.children.isNewCreate.value
) {
@@ -285,6 +329,12 @@ function QueryView(props: QueryViewProps) {
comp.dispatch(deferAction(executeQueryAction({})));
}, 300);
}
+
+ if(getTriggerType(comp) === "onTimeout") {
+ setTimeout(() => {
+ comp.dispatch(deferAction(executeQueryAction({})));
+ }, comp.children.delayTime.getView());
+ }
}, []);
useFixedDelay(
@@ -292,9 +342,9 @@ function QueryView(props: QueryViewProps) {
getPromiseAfterDispatch(comp.dispatch, executeQueryAction({}), {
notHandledError: trans("query.fixedDelayError"),
}),
- getTriggerType(comp) === "automatic" && comp.children.periodic.getView()
- ? comp.children.periodicTime.getView()
- : null
+ getTriggerType(comp) === "automatic" && comp.children.periodic.getView()
+ ? comp.children.periodicTime.getView()
+ : null
);
return null;
@@ -609,6 +659,29 @@ export const QueryComp = withExposingConfigs(QueryCompTmp, [
const QueryListTmpComp = list(QueryComp);
class QueryListComp extends QueryListTmpComp implements BottomResListComp {
+ override reduce(action: CompAction): this {
+ if (isCustomAction(action, "afterExecQuery")) {
+ if (action.path?.length === 1 && !isNaN(parseInt(action.path[0]))) {
+ const queryIdx = parseInt(action.path[0]);
+ const queryComps = this.getView();
+ const queryName = queryComps?.[queryIdx]?.children.name.getView();
+ const dependentQueries = queryComps.filter((query, idx) => {
+ if (queryIdx === idx) return false;
+ if (
+ getTriggerType(query) === 'onQueryExecution'
+ && query.children.depQueryName.getView() === queryName
+ ) {
+ return true;
+ }
+ })
+ dependentQueries?.forEach((query) => {
+ query.dispatch(deferAction(executeQueryAction({})));
+ })
+ }
+ }
+ return super.reduce(action);
+ }
+
nameAndExposingInfo(): NameAndExposingInfo {
const result: NameAndExposingInfo = {};
Object.values(this.children).forEach((comp) => {
diff --git a/client/packages/lowcoder/src/comps/queries/queryComp/queryPropertyView.tsx b/client/packages/lowcoder/src/comps/queries/queryComp/queryPropertyView.tsx
index 910365185..07f4ef1e0 100644
--- a/client/packages/lowcoder/src/comps/queries/queryComp/queryPropertyView.tsx
+++ b/client/packages/lowcoder/src/comps/queries/queryComp/queryPropertyView.tsx
@@ -26,7 +26,7 @@ import { useSelector } from "react-redux";
import { getDataSource, getDataSourceTypes } from "redux/selectors/datasourceSelectors";
import { BottomResTypeEnum } from "types/bottomRes";
import { EditorContext } from "../../editorState";
-import { QueryComp } from "../queryComp";
+import { JSTriggerTypeOptions, QueryComp, TriggerType, TriggerTypeOptions } from "../queryComp";
import { ResourceDropdown } from "../resourceDropdown";
import { NOT_SUPPORT_GUI_SQL_QUERY, SQLQuery } from "../sqlQuery/SQLQuery";
import { StreamQuery } from "../httpQuery/streamQuery";
@@ -37,6 +37,7 @@ import styled from "styled-components";
import { DataSourceButton } from "pages/datasource/pluginPanel";
import { Tooltip, Divider } from "antd";
import { uiCompRegistry } from "comps/uiCompRegistry";
+import { InputTypeEnum } from "@lowcoder-ee/comps/comps/moduleContainerComp/ioComp/inputListItemComp";
const Wrapper = styled.div`
width: 100%;
@@ -226,6 +227,42 @@ export const QueryGeneralPropertyView = (props: {
comp.children.datasourceId.dispatchChangeValueAction(QUICK_REST_API_ID);
}
+ const triggerOptions = useMemo(() => {
+ if (datasourceType === "js" || datasourceType === "streamApi") {
+ return JSTriggerTypeOptions;
+ }
+ return TriggerTypeOptions;
+ }, [datasourceType]);
+
+ const getQueryOptions = useMemo(() => {
+ const options: { label: string; value: string }[] =
+ editorState
+ ?.queryCompInfoList()
+ .map((info) => ({
+ label: info.name,
+ value: info.name,
+ }))
+ .filter((option) => {
+ // Filter out the current query under query
+ if (editorState.selectedBottomResType === BottomResTypeEnum.Query) {
+ return option.value !== editorState.selectedBottomResName;
+ }
+ return true;
+ }) || [];
+
+ // input queries
+ editorState
+ ?.getModuleLayoutComp()
+ ?.getInputs()
+ .forEach((i) => {
+ const { name, type } = i.getView();
+ if (type === InputTypeEnum.Query) {
+ options.push({ label: name, value: name });
+ }
+ });
+ return options;
+ }, [editorState]);
+
return (
@@ -329,26 +366,38 @@ export const QueryGeneralPropertyView = (props: {
{placement === "editor" && (
-
- children.triggerType.dispatchChangeValueAction(value)}
- />
-
+ <>
+
+ children.triggerType.dispatchChangeValueAction(value as TriggerType)}
+ />
+
+ {children.triggerType.getView() === 'onQueryExecution' && (
+
+ children.depQueryName.dispatchChangeValueAction(value)}
+ />
+
+ )}
+ {children.triggerType.getView() === 'onTimeout' && (
+
+ {children.delayTime.propertyView({
+ label: trans("query.delayTime"),
+ placeholder: "5s",
+ placement: "bottom",
+ })}
+
+ )}
+ >
)}
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index baef755e8..be0378e20 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -738,6 +738,10 @@ export const en = {
"triggerTypeAuto": "Inputs Change or On Page Load",
"triggerTypePageLoad": "When the Application (Page) loads",
"triggerTypeManual": "Only when you trigger it manually",
+ "triggerTypeInputChange": "When Inputs Change",
+ "triggerTypeQueryExec": "After Query Execution",
+ "triggerTypeTimeout": "After the Timeout Interval",
+ "delayTime": "Delay Time",
"chooseDataSource": "Choose Data Source",
"method": "Method",
"updateExceptionDataSourceTitle": "Update Failing Data Source",
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/lowcoder-org/lowcoder/pull/1443.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy