tree level UI updated

This commit is contained in:
vicky_primathon.in 2020-05-28 10:02:50 +05:30
parent 24b60c7b71
commit 263ac8aafb
2 changed files with 146 additions and 21 deletions

View File

@ -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 (
<FieldWrapper>
<ControlWrapper key={props.label} level={props.level}>
@ -187,16 +191,40 @@ const views = {
level={props.level}
/>
) : null}
{props.level ? (
<TreeStructureVerticalWrapper
label={props.label}
level={props.level}
/>
) : null}
{(() => {
if (
props.level &&
props.levelSeparator &&
props.levelSeparator === "odd"
) {
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>
);
},
[ViewTypes.KEY_VALUE_VIEW]: function KeyValueView(props: KeyValueViewProps) {
// console.log(props.label, props.level, props.levelSeparator, props.value);
return (
<ControlWrapper key={props.label}>
<KeyValueComponent
@ -208,6 +236,7 @@ const views = {
);
},
[ViewTypes.TEXT_VIEW]: function TextView(props: TextViewProps) {
console.log(props.label, props.level, props.levelSeparator, props.value);
return (
<FieldWrapper>
<ControlWrapper key={props.label} level={props.level}>
@ -232,12 +261,35 @@ const views = {
level={props.level}
/>
) : null}
{props.level ? (
<TreeStructureVerticalWrapper
label={props.label}
level={props.level}
/>
) : null}
{(() => {
if (
props.level &&
props.levelSeparator &&
props.levelSeparator === "odd"
) {
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>
);
},
@ -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}

View File

@ -26,7 +26,7 @@ export const ControlWrapper = styled.div<ControlWrapperProps>`
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;
`;