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