Merge branch 'release' of gitlab.com:theappsmith/internal-tools-client into release

This commit is contained in:
Nikhil Nandagopal 2019-11-12 12:06:46 +05:30
commit 2cc0e13006
4 changed files with 268 additions and 54 deletions

View File

@ -14,34 +14,91 @@ import { connect } from "react-redux";
import { AppState } from "../../reducers";
import { ActionDataState } from "../../reducers/entityReducers/actionsReducer";
const DEFAULT_ACTION_TYPE = "Select Action Type";
const DEFAULT_ACTION_TYPE = "Select Action Type" as ActionType;
const DEFAULT_ACTION_LABEL = "Select Action";
enum ACTION_RESOLUTION_TYPE {
SUCCESS,
ERROR,
}
function getActions(
actionPayloads: ActionPayload[] | undefined,
): {
action: ActionPayload | undefined;
onSuccessAction: ActionPayload | undefined;
onErrorAction: ActionPayload | undefined;
} {
let action: ActionPayload | undefined = actionPayloads && actionPayloads[0];
let onSuccessAction: ActionPayload | undefined =
action && action.onSuccess && action.onSuccess[0];
let onErrorAction: ActionPayload | undefined =
action && action.onError && action.onError[0];
return {
action,
onSuccessAction,
onErrorAction,
};
}
class ActionSelectorControl extends BaseControl<
ControlProps & ActionDataState
> {
getSelectionActionType(): string {
const selectedActionTypeValue =
this.props.propertyValue &&
this.props.propertyValue[0] &&
this.props.propertyValue[0].actionType;
getSelectionActionType(type: ACTION_RESOLUTION_TYPE | string): ActionType {
let selectedActionTypeValue: ActionType | undefined;
const { action, onSuccessAction, onErrorAction } = getActions(
this.props.propertyValue,
);
switch (type) {
case this.props.propertyName:
selectedActionTypeValue = action && action.actionType;
break;
case ACTION_RESOLUTION_TYPE.SUCCESS:
selectedActionTypeValue = onSuccessAction && onSuccessAction.actionType;
break;
case ACTION_RESOLUTION_TYPE.ERROR:
selectedActionTypeValue = onErrorAction && onErrorAction.actionType;
break;
default:
break;
}
const foundActionType = PropertyPaneActionDropdownOptions.find(
actionType => actionType.value === selectedActionTypeValue,
);
return foundActionType ? foundActionType.label : DEFAULT_ACTION_TYPE;
return foundActionType
? (foundActionType.label as ActionType)
: DEFAULT_ACTION_TYPE;
}
getSelectionActionLabel(allActions: DropdownOption[]): string {
const selectedActionId =
this.props.propertyValue &&
this.props.propertyValue[0] &&
this.props.propertyValue[0].actionId;
getSelectionActionLabel(
type: ACTION_RESOLUTION_TYPE | string,
allActions: DropdownOption[],
): string {
let selectedActionId: string | undefined = "";
const { action, onSuccessAction, onErrorAction } = getActions(
this.props.propertyValue,
);
switch (type) {
case this.props.propertyName:
selectedActionId = action && action.actionId;
break;
case ACTION_RESOLUTION_TYPE.SUCCESS:
selectedActionId = onSuccessAction && onSuccessAction.actionId;
break;
case ACTION_RESOLUTION_TYPE.ERROR:
selectedActionId = onErrorAction && onErrorAction.actionId;
break;
default:
break;
}
const foundAction = allActions.find(
action => action.value === selectedActionId,
);
return foundAction ? foundAction.label : "Select Action";
return foundAction ? foundAction.label : DEFAULT_ACTION_LABEL;
}
render() {
const actionTypeOptions: DropdownOption[] = PropertyPaneActionDropdownOptions;
@ -51,16 +108,98 @@ class ActionSelectorControl extends BaseControl<
value: action.id,
};
});
const selectedActionType = this.getSelectionActionType();
const selectedActionLabel = this.getSelectionActionLabel(allActions);
const selectedActionType = this.getSelectionActionType(
this.props.propertyName,
);
const selectedActionLabel = this.getSelectionActionLabel(
this.props.propertyName,
allActions,
);
const selectedSuccessActionType = this.getSelectionActionType(
ACTION_RESOLUTION_TYPE.SUCCESS,
);
const selectedSuccessActionLabel = this.getSelectionActionLabel(
ACTION_RESOLUTION_TYPE.SUCCESS,
allActions,
);
const selectedErrorActionType = this.getSelectionActionType(
ACTION_RESOLUTION_TYPE.ERROR,
);
const selectedErrorActionLabel = this.getSelectionActionLabel(
ACTION_RESOLUTION_TYPE.ERROR,
allActions,
);
return (
<ControlWrapper>
<label>{this.props.label}</label>
{this.renderActionSelector(
allActions,
actionTypeOptions,
selectedActionType,
selectedActionLabel,
this.props.propertyName,
this.props.propertyName,
)}
{selectedActionLabel !== DEFAULT_ACTION_LABEL &&
this.renderActionSelector(
allActions,
actionTypeOptions,
selectedSuccessActionType,
selectedSuccessActionLabel,
"On Success",
ACTION_RESOLUTION_TYPE.SUCCESS,
)}
{selectedActionLabel !== DEFAULT_ACTION_LABEL &&
this.renderActionSelector(
allActions,
actionTypeOptions,
selectedErrorActionType,
selectedErrorActionLabel,
"On Error",
ACTION_RESOLUTION_TYPE.ERROR,
)}
</ControlWrapper>
);
}
renderActionSelector(
allActions: DropdownOption[],
actionTypeOptions: DropdownOption[],
selectedActionType: ActionType,
selectedActionLabel: string,
label: string,
actionResolutionType: ACTION_RESOLUTION_TYPE | string,
) {
let onTypeSelect = this.onActionTypeSelect;
switch (actionResolutionType) {
case ACTION_RESOLUTION_TYPE.SUCCESS:
onTypeSelect = this.onSuccessActionTypeSelect;
break;
case ACTION_RESOLUTION_TYPE.ERROR:
onTypeSelect = this.onErrorActionTypeSelect;
break;
}
let onActionSelect = this.onActionSelect;
switch (actionResolutionType) {
case ACTION_RESOLUTION_TYPE.SUCCESS:
onTypeSelect = this.onSuccessActionSelect;
break;
case ACTION_RESOLUTION_TYPE.ERROR:
onTypeSelect = this.onErrorActionSelect;
break;
}
return (
<div>
<div>
<label>{label}</label>
</div>
<StyledDropDown
items={actionTypeOptions}
filterable={false}
itemRenderer={this.renderItem}
onItemSelect={this.onTypeSelect}
onItemSelect={onTypeSelect}
noResults={<MenuItem disabled={true} text="No results." />}
>
<Button text={selectedActionType} rightIcon="chevron-down" />
@ -71,23 +210,25 @@ class ActionSelectorControl extends BaseControl<
items={allActions}
filterable={false}
itemRenderer={this.renderItem}
onItemSelect={this.onActionSelect}
onItemSelect={onActionSelect}
noResults={<MenuItem disabled={true} text="No results." />}
>
<Button text={selectedActionLabel} rightIcon="chevron-down" />
</StyledDropDown>
)}
</ControlWrapper>
</div>
);
}
onTypeSelect = (item: DropdownOption): void => {
onActionTypeSelect = (item: DropdownOption) => {
const actionPayloads: ActionPayload[] = this.props.propertyValue
? this.props.propertyValue.slice()
: [];
const actionPayload = actionPayloads[0];
if (actionPayload) {
let actionPayload = actionPayloads[0];
if (actionPayload && actionPayload.actionType !== item.value) {
actionPayload.actionId = "";
actionPayload.onError = undefined;
actionPayload.onSuccess = undefined;
actionPayload.actionType = item.value as ActionType;
} else {
const actionPayload = { actionType: item.value } as ActionPayload;
@ -95,16 +236,83 @@ class ActionSelectorControl extends BaseControl<
}
this.updateProperty(this.props.propertyName, actionPayloads);
};
onSuccessActionTypeSelect = (item: DropdownOption) => {
const actionPayloads: ActionPayload[] = this.props.propertyValue
? this.props.propertyValue.slice()
: [];
let actionPayload = actionPayloads[0];
if (actionPayload) {
const successActionPayloads: ActionPayload[] =
actionPayload.onSuccess || [];
let successActionPayload = successActionPayloads[0];
if (successActionPayload) {
successActionPayload.actionId = "";
successActionPayload.actionType = item.value as ActionType;
} else {
const successActionPayload = {
actionType: item.value,
} as ActionPayload;
successActionPayloads.push(successActionPayload);
}
actionPayload.onSuccess = successActionPayloads;
}
this.updateProperty(this.props.propertyName, actionPayloads);
};
onErrorActionTypeSelect = (item: DropdownOption) => {
const actionPayloads: ActionPayload[] = this.props.propertyValue
? this.props.propertyValue.slice()
: [];
let actionPayload = actionPayloads[0];
if (actionPayload) {
const errorActionPayloads: ActionPayload[] = actionPayload.onError || [];
let errorActionPayload = errorActionPayloads[0];
if (errorActionPayload) {
errorActionPayload.actionId = "";
errorActionPayload.actionType = item.value as ActionType;
} else {
const errorActionPayload = {
actionType: item.value,
} as ActionPayload;
errorActionPayloads.push(errorActionPayload);
}
actionPayload.onError = errorActionPayloads;
}
this.updateProperty(this.props.propertyName, actionPayloads);
};
onActionSelect = (item: DropdownOption): void => {
const actionPayloads: ActionPayload[] = this.props.propertyValue
? this.props.propertyValue.slice()
: [];
const actionPayload = actionPayloads[0];
actionPayload.actionId = item.value as ActionType;
actionPayload.actionId = item.value;
this.updateProperty(this.props.propertyName, actionPayloads);
};
onSuccessActionSelect = (item: DropdownOption): void => {
const actionPayloads: ActionPayload[] = this.props.propertyValue
? this.props.propertyValue.slice()
: [];
const actionPayload = actionPayloads[0];
const successActionPayloads: ActionPayload[] = actionPayload.onSuccess as ActionPayload[];
const successActionPayload = successActionPayloads[0];
successActionPayload.actionId = item.value;
actionPayload.onSuccess = successActionPayloads;
this.updateProperty(this.props.propertyName, actionPayloads);
};
onErrorActionSelect = (item: DropdownOption): void => {
const actionPayloads: ActionPayload[] = this.props.propertyValue
? this.props.propertyValue.slice()
: [];
const actionPayload = actionPayloads[0];
const errorActionPayloads: ActionPayload[] = actionPayload.onError as ActionPayload[];
const errorActionPayload = errorActionPayloads[0];
errorActionPayload.actionId = item.value;
actionPayload.onError = errorActionPayloads;
this.updateProperty(this.props.propertyName, actionPayloads);
};
renderItem = (option: DropdownOption, itemProps: IItemRendererProps) => {
if (!itemProps.modifiers.matchesPredicate) {

View File

@ -22,16 +22,6 @@ export type ActionType =
| "SET_VALUE"
| "DOWNLOAD";
export enum ActionType1 {
"API",
"QUERY",
"NAVIGATION",
"ALERT",
"JS_FUNCTION",
"SET_VALUE",
"DOWNLOAD",
}
export const PropertyPaneActionDropdownOptions: DropdownOption[] = [
{ label: "Call API", value: "API" },
// { label: "Run Query", value: "QUERY" },
@ -41,6 +31,8 @@ export interface ActionPayload {
actionId: string;
actionType: ActionType;
contextParams: Record<string, string>;
onSuccess?: ActionPayload[];
onError?: ActionPayload[];
}
export type NavigationType = "NEW_TAB" | "INLINE";

View File

@ -80,6 +80,13 @@ export function* executeAPIQueryActionSaga(apiAction: { actionId: string }) {
statusCode: response.responseMeta.error.code,
...response,
};
if (apiAction.onError) {
yield call(executeActionSaga, apiAction.onError);
}
} else {
if (apiAction.onSuccess) {
yield call(executeActionSaga, apiAction.onSuccess);
}
}
yield put({
type: ReduxActionTypes.EXECUTE_ACTION_SUCCESS,
@ -88,19 +95,25 @@ export function* executeAPIQueryActionSaga(apiAction: { actionId: string }) {
return response;
}
export function* executeActionSaga(action: ReduxAction<ActionPayload[]>) {
// TODO(satbir): Refact this to not make this recursive.
export function* executeActionSaga(actionPayloads: ActionPayload[]): any {
yield all(
_.map(actionPayloads, (actionPayload: ActionPayload) => {
switch (actionPayload.actionType) {
case "API":
return call(executeAPIQueryActionSaga, actionPayload);
case "QUERY":
return call(executeAPIQueryActionSaga, actionPayload);
default:
return undefined;
}
}),
);
}
export function* executeReduxActionSaga(action: ReduxAction<ActionPayload[]>) {
if (!_.isNil(action.payload)) {
yield all(
_.map(action.payload, (actionPayload: ActionPayload) => {
switch (actionPayload.actionType) {
case "API":
return call(executeAPIQueryActionSaga, actionPayload);
case "QUERY":
return call(executeAPIQueryActionSaga, actionPayload);
}
return undefined;
}),
);
yield call(executeActionSaga, action.payload);
}
}
@ -181,7 +194,7 @@ export function* deleteActionSaga(actionPayload: ReduxAction<{ id: string }>) {
export function* watchActionSagas() {
yield all([
takeEvery(ReduxActionTypes.FETCH_ACTIONS_INIT, fetchActionsSaga),
takeLatest(ReduxActionTypes.EXECUTE_ACTION, executeActionSaga),
takeLatest(ReduxActionTypes.EXECUTE_ACTION, executeReduxActionSaga),
takeLatest(ReduxActionTypes.CREATE_ACTION_INIT, createActionSaga),
takeLatest(ReduxActionTypes.UPDATE_ACTION_INIT, updateActionSaga),
takeLatest(ReduxActionTypes.DELETE_ACTION_INIT, deleteActionSaga),

View File

@ -57,13 +57,13 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
data={tableData}
maxHeight={height}
selectedRowIndex={
this.props.selectedRow && this.props.selectedRow.index
this.props.selectedRow && this.props.selectedRow.rowIndex
}
onRowClick={(rowData: object, index: number) => {
const { widgetId, onRowSelected } = this.props;
super.updateWidgetProperty(widgetId, "selectedRow", {
data: rowData,
index: index,
...rowData,
rowIndex: index,
});
super.executeAction(onRowSelected);
}}
@ -84,6 +84,10 @@ export interface TableAction extends ActionPayload {
actionName: string;
}
interface RowData {
rowIndex: number;
}
export interface TableWidgetProps extends WidgetProps {
nextPageKey?: string;
prevPageKey?: string;
@ -92,10 +96,7 @@ export interface TableWidgetProps extends WidgetProps {
recordActions?: TableAction[];
onPageChange?: ActionPayload[];
onRowSelected?: ActionPayload[];
selectedRow?: {
data: object;
index: number;
};
selectedRow?: object & RowData;
}
export default TableWidget;