diff --git a/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx b/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx
index 1a282fe775..26f7c82669 100644
--- a/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx
+++ b/app/client/src/components/editorComponents/actioncreator/ActionCreator.tsx
@@ -19,7 +19,7 @@ import {
import { KeyValueComponent } from "components/propertyControls/KeyValueComponent";
import { InputText } from "components/propertyControls/InputTextControl";
import { createModalAction } from "actions/widgetActions";
-import { createNewApiName } from "utils/AppsmithUtils";
+import { createNewApiName, createNewQueryName } from "utils/AppsmithUtils";
import { isDynamicValue } from "utils/DynamicBindingUtils";
import { createNewApiAction } from "actions/apiPaneActions";
@@ -124,6 +124,7 @@ type ActionCreatorProps = {
const ActionType = {
none: "none",
api: "api",
+ query: "query",
showModal: "showModal",
closeModal: "closeModal",
navigateTo: "navigateTo",
@@ -149,6 +150,7 @@ type SelectorViewProps = ViewProps & {
defaultText: string;
getDefaults?: Function;
level: number;
+ levelSeparator?: string;
displayValue?: string;
selectedLabelModifier?: (
option: TreeDropdownOption,
@@ -161,10 +163,12 @@ type TextViewProps = ViewProps & {
isValid: boolean;
validationMessage?: string;
level: number;
+ levelSeparator?: string;
};
const views = {
[ViewTypes.SELECTOR_VIEW]: function SelectorView(props: SelectorViewProps) {
+ console.log(props.label, props.level, props.levelSeparator, props.value);
return (
@@ -187,16 +191,40 @@ const views = {
level={props.level}
/>
) : null}
- {props.level ? (
-
- ) : null}
+ {(() => {
+ if (
+ props.level &&
+ props.levelSeparator &&
+ props.levelSeparator === "odd"
+ ) {
+ const treeStructureVerticalWrappers = new Array(props.level)
+ .fill("")
+ .map((i, index) => {
+ return (
+
+ );
+ });
+ return treeStructureVerticalWrappers;
+ } else if (props.level) {
+ return (
+
+ );
+ } else {
+ return [];
+ }
+ })()}
);
},
[ViewTypes.KEY_VALUE_VIEW]: function KeyValueView(props: KeyValueViewProps) {
+ // console.log(props.label, props.level, props.levelSeparator, props.value);
return (
@@ -232,12 +261,35 @@ const views = {
level={props.level}
/>
) : null}
- {props.level ? (
-
- ) : null}
+ {(() => {
+ if (
+ props.level &&
+ props.levelSeparator &&
+ props.levelSeparator === "odd"
+ ) {
+ const treeStructureVerticalWrappers = new Array(props.level)
+ .fill("")
+ .map((i, index) => {
+ return (
+
+ );
+ });
+ return treeStructureVerticalWrappers;
+ } else if (props.level) {
+ return (
+
+ );
+ } else {
+ return [];
+ }
+ })()}
);
},
@@ -293,6 +345,7 @@ const fieldConfigs: FieldConfigs = {
let value = option.value;
switch (type) {
case ActionType.api:
+ case ActionType.query:
value = `${value}.run`;
break;
default:
@@ -376,6 +429,10 @@ const baseOptions: any = [
label: "Call API",
value: ActionType.api,
},
+ {
+ label: "Execute Query",
+ value: ActionType.query,
+ },
{
label: "Show Modal",
value: ActionType.showModal,
@@ -416,13 +473,16 @@ function getOptionsWithChildren(
function getFieldFromValue(
value: string | undefined,
level: number,
+ levelSeparator?: string,
getParentValue?: Function,
): any[] {
const fields: any[] = [
{
field: FieldType.ACTION_SELECTOR_FIELD,
- getParentValue: getParentValue,
- value: value,
+ getParentValue,
+ value,
+ level,
+ levelSeparator,
},
];
if (!value) {
@@ -442,6 +502,7 @@ function getFieldFromValue(
const successFields = getFieldFromValue(
`{{${sucesssValue}}}`,
level + 1,
+ "odd",
(changeValue: string) => {
const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
const args = [...matches[0][2].matchAll(ACTION_ANONYMOUS_FUNC_REGEX)];
@@ -468,6 +529,7 @@ function getFieldFromValue(
const errorFields = getFieldFromValue(
`{{${errorValue}}}`,
level + 1,
+ "even",
(changeValue: string) => {
const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
const args = [...matches[0][2].matchAll(ACTION_ANONYMOUS_FUNC_REGEX)];
@@ -493,6 +555,7 @@ function getFieldFromValue(
fields.push({
field: FieldType.URL_FIELD,
level: level + 1,
+ levelSeparator,
});
}
@@ -500,12 +563,14 @@ function getFieldFromValue(
fields.push({
field: FieldType.SHOW_MODAL_FIELD,
level: level + 1,
+ levelSeparator,
});
}
if (value.indexOf("closeModal") !== -1) {
fields.push({
field: FieldType.CLOSE_MODAL_FIELD,
level: level + 1,
+ levelSeparator,
});
}
if (value.indexOf("showAlert") !== -1) {
@@ -513,10 +578,12 @@ function getFieldFromValue(
{
field: FieldType.ALERT_TEXT_FIELD,
level: level + 1,
+ levelSeparator,
},
{
field: FieldType.ALERT_TYPE_SELECTOR_FIELD,
level: level + 1,
+ levelSeparator,
},
);
}
@@ -539,6 +606,7 @@ function Fields(props: {
isValid: boolean;
validationMessage?: string;
apiOptionTree: TreeDropdownOption[];
+ queryOptionTree: TreeDropdownOption[];
modalDropdownList: TreeDropdownOption[];
pageDropdownOptions: TreeDropdownOption[];
depth: number;
@@ -558,6 +626,7 @@ function Fields(props: {
isValid={props.isValid}
validationMessage={props.validationMessage}
apiOptionTree={props.apiOptionTree}
+ queryOptionTree={props.queryOptionTree}
modalDropdownList={props.modalDropdownList}
pageDropdownOptions={props.pageDropdownOptions}
depth={props.depth + 1}
@@ -600,7 +669,10 @@ function Fields(props: {
option: TreeDropdownOption,
displayValue?: string,
) => {
- if (option.type === ActionType.api) {
+ if (
+ option.type === ActionType.api ||
+ option.type === ActionType.query
+ ) {
return `{{${option.label}.run()}}`;
// return `Call ${option.label}`;
} else if (displayValue) {
@@ -650,6 +722,7 @@ function Fields(props: {
selectedLabelModifier: selectedLabelModifier,
displayValue: displayValue,
level: field.level,
+ levelSeparator: field.levelSeparator,
});
break;
case FieldType.KEY_VALUE_FIELD:
@@ -664,6 +737,7 @@ function Fields(props: {
value: props.value,
defaultText: "Select Action",
level: field.level,
+ levelSeparator: field.levelSeparator,
});
break;
case FieldType.ALERT_TEXT_FIELD:
@@ -679,6 +753,7 @@ function Fields(props: {
isValid: props.isValid,
validationMessage: props.validationMessage,
level: field.level,
+ levelSeparator: field.levelSeparator,
});
break;
default:
@@ -724,7 +799,9 @@ function useApiOptionTree() {
const dispatch = useDispatch();
const pageId = useSelector(getCurrentPageId) || "";
- const actions = useSelector(getActionsForCurrentPage);
+ const actions = useSelector(getActionsForCurrentPage).filter(
+ action => action.config.pluginType === "API",
+ );
const apiOptionTree = getOptionsWithChildren(baseOptions, actions, {
label: "Create Api",
value: "api",
@@ -744,8 +821,55 @@ function useApiOptionTree() {
return apiOptionTree;
}
+function getQueryOptionsWithChildren(
+ options: TreeDropdownOption[],
+ queries: ActionDataState,
+ createQueryOption: TreeDropdownOption,
+) {
+ const option = options.find(option => option.value === ActionType.query);
+ if (option) {
+ option.children = [createQueryOption];
+ queries.forEach(query => {
+ (option.children as TreeDropdownOption[]).push({
+ label: query.config.name,
+ id: query.config.id,
+ value: query.config.name,
+ type: option.value,
+ } as TreeDropdownOption);
+ });
+ }
+ return options;
+}
+
+function useQueryOptionTree() {
+ const dispatch = useDispatch();
+ const pageId = useSelector(getCurrentPageId) || "";
+
+ const queries = useSelector(getActionsForCurrentPage).filter(
+ action => action.config.pluginType === "DB",
+ );
+ const queryOptionTree = getQueryOptionsWithChildren(baseOptions, queries, {
+ label: "Create Query",
+ value: "query",
+ id: "create",
+ className: "t--create-query-btn",
+ onSelect: (option: TreeDropdownOption, setter?: Function) => {
+ const queryName = createNewQueryName(queries, pageId);
+ if (setter) {
+ setter({
+ value: `${queryName}`,
+ type: ActionType.query,
+ });
+ // dispatch(createNewQueryAction(pageId));
+ }
+ },
+ });
+ return queryOptionTree;
+}
+
export function ActionCreator(props: ActionCreatorProps) {
const apiOptionTree = useApiOptionTree();
+ const queryOptionTree = useQueryOptionTree();
const modalDropdownList = useModalDropdownList();
const pageDropdownOptions = useSelector(getPageDropdownOptions);
const fields = getFieldFromValue(props.value, 0);
@@ -756,6 +880,7 @@ export function ActionCreator(props: ActionCreatorProps) {
isValid={props.isValid}
validationMessage={props.validationMessage}
apiOptionTree={apiOptionTree}
+ queryOptionTree={queryOptionTree}
modalDropdownList={modalDropdownList}
pageDropdownOptions={pageDropdownOptions}
onValueChange={props.onValueChange}
diff --git a/app/client/src/components/propertyControls/StyledControls.tsx b/app/client/src/components/propertyControls/StyledControls.tsx
index f70a8ab7dc..c04c793a73 100644
--- a/app/client/src/components/propertyControls/StyledControls.tsx
+++ b/app/client/src/components/propertyControls/StyledControls.tsx
@@ -26,7 +26,7 @@ export const ControlWrapper = styled.div`
flex-direction: ${props =>
props.orientation === "VERTICAL" ? "column" : "row"}
padding: ${props => props.theme.spaces[3]}px 0;
- padding-left: ${props => (props.level ? 18 : 0)}px;
+ padding-left: ${props => (props.level ? 18 * props.level : 0)}px;
& > label {
color: ${props => props.theme.colors.paneText};
margin-bottom: ${props => props.theme.spaces[1]}px;
@@ -306,11 +306,11 @@ export const TreeStructureHorizontalWrapper = styled.div<{
label: string;
}>`
position: absolute;
- width: calc(100% - 9px);
+ width: calc(100% - ${props => (props.level - 1) * 18 + 9}px);
height: 2px;
background: #a2a6a8;
top: ${props => (props.label ? "66.66%" : "50%")};
- left: 9px;
+ left: ${props => (props.level - 1) * 18 + 9}px;
z-index: -1;
`;
@@ -323,6 +323,6 @@ export const TreeStructureVerticalWrapper = styled.div<{
width: 2px;
background: #a2a6a8;
top: ${props => (props.label ? "-33.33%" : "-50%")};
- left: 9px;
+ left: ${props => (props.level - 1) * 18 + 9}px;
z-index: -1;
`;