Merge branch 'hide-new-api-pane' into 'release'
Add a feature flag for new api pane See merge request theappsmith/internal-tools-client!499
This commit is contained in:
commit
dcf320e4e6
|
|
@ -13,3 +13,10 @@ export const initApiPane = (urlId?: string): ReduxAction<{ id?: string }> => {
|
|||
payload: { id: urlId },
|
||||
};
|
||||
};
|
||||
|
||||
export const createNewApiAction = (
|
||||
pageId: string,
|
||||
): ReduxAction<{ pageId: string }> => ({
|
||||
type: ReduxActionTypes.CREATE_NEW_API_ACTION,
|
||||
payload: { pageId },
|
||||
});
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ export const ReduxActionTypes: { [key: string]: string } = {
|
|||
CLEAR_PROVIDERS: "CLEAR_PROVIDERS",
|
||||
BATCHED_UPDATE: "BATCHED_UPDATE",
|
||||
EXECUTE_BATCH: "EXECUTE_BATCH",
|
||||
CREATE_NEW_API_ACTION: "CREATE_NEW_API_ACTION",
|
||||
};
|
||||
|
||||
export type ReduxActionType = typeof ReduxActionTypes[keyof typeof ReduxActionTypes];
|
||||
|
|
|
|||
|
|
@ -5,11 +5,7 @@ import { reduxForm, InjectedFormProps, getFormValues } from "redux-form";
|
|||
import { Icon, Card } from "@blueprintjs/core";
|
||||
import styled from "styled-components";
|
||||
import InfiniteScroll from "react-infinite-scroller";
|
||||
import {
|
||||
DEFAULT_API_ACTION,
|
||||
DEFAULT_PROVIDER_OPTION,
|
||||
REST_PLUGIN_PACKAGE_NAME,
|
||||
} from "constants/ApiEditorConstants";
|
||||
import { DEFAULT_PROVIDER_OPTION } from "constants/ApiEditorConstants";
|
||||
import {
|
||||
getCurlImportPageURL,
|
||||
getProviderTemplatesURL,
|
||||
|
|
@ -35,7 +31,6 @@ import {
|
|||
fetchProvidersWithCategory,
|
||||
clearProviders,
|
||||
} from "actions/providerActions";
|
||||
import { createNewApiName } from "utils/AppsmithUtils";
|
||||
import { Colors } from "constants/Colors";
|
||||
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
|
||||
// import { BaseTextInput } from "components/designSystems/appsmith/TextInputComponent";
|
||||
|
|
@ -46,7 +41,7 @@ import Spinner from "components/editorComponents/Spinner";
|
|||
import CurlLogo from "assets/images/Curl-logo.svg";
|
||||
import { FetchProviderWithCategoryRequest } from "api/ProvidersApi";
|
||||
import { Plugin } from "api/PluginApi";
|
||||
import _ from "lodash";
|
||||
import { createNewApiAction } from "actions/apiPaneActions";
|
||||
|
||||
// const SearchContainer = styled.div`
|
||||
// display: flex;
|
||||
|
|
@ -241,6 +236,7 @@ type ApiHomeScreenProps = {
|
|||
isFetchingProviders: boolean;
|
||||
providersTotal: number;
|
||||
isSwitchingCategory: boolean;
|
||||
createNewApiAction: (pageId: string) => void;
|
||||
};
|
||||
|
||||
type ApiHomeScreenState = {
|
||||
|
|
@ -283,20 +279,9 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
|
|||
}
|
||||
|
||||
handleCreateNew = (params: string) => {
|
||||
const { actions, plugins } = this.props;
|
||||
const pageId = new URLSearchParams(params).get("importTo");
|
||||
const plugin = _.find(plugins, { packageName: REST_PLUGIN_PACKAGE_NAME });
|
||||
if (pageId && plugin) {
|
||||
const newActionName = createNewApiName(actions, pageId);
|
||||
this.props.createAction({
|
||||
...DEFAULT_API_ACTION,
|
||||
name: newActionName,
|
||||
datasource: {
|
||||
name: "DEFAULT_REST_DATASOURCE",
|
||||
pluginId: plugin.id,
|
||||
},
|
||||
pageId,
|
||||
});
|
||||
if (pageId) {
|
||||
this.props.createNewApiAction(pageId);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -560,6 +545,7 @@ const mapDispatchToProps = (dispatch: any) => ({
|
|||
dispatch(fetchProvidersWithCategory(request)),
|
||||
createAction: (data: Partial<RestAction>) =>
|
||||
dispatch(createActionRequest(data)),
|
||||
createNewApiAction: (pageId: string) => dispatch(createNewApiAction(pageId)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@ import AnalyticsUtil from "utils/AnalyticsUtil";
|
|||
import { getCurrentPageName, getActionById } from "selectors/editorSelectors";
|
||||
import { Plugin } from "api/PluginApi";
|
||||
import { ActionData } from "reducers/entityReducers/actionsReducer";
|
||||
import { API_PANE_V2, checkForFlag } from "utils/featureFlags";
|
||||
import styled from "styled-components";
|
||||
|
||||
const EmptyStateContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
font-size: 20px;
|
||||
`;
|
||||
|
||||
interface ReduxStateProps {
|
||||
actions: ActionDataState;
|
||||
|
|
@ -139,6 +149,21 @@ class ApiEditor extends React.Component<Props> {
|
|||
|
||||
const { isSaving, isRunning, isDeleting, drafts } = apiPane;
|
||||
const paginationType = _.get(data, "actionConfiguration.paginationType");
|
||||
const apiHomeScreen = (
|
||||
<ApiHomeScreen
|
||||
applicationId={this.props.match.params.applicationId}
|
||||
pageId={this.props.match.params.pageId}
|
||||
history={this.props.history}
|
||||
location={this.props.location}
|
||||
/>
|
||||
);
|
||||
const defaultHomeScreen = (
|
||||
<EmptyStateContainer>
|
||||
{"Create / Select an API from the list"}
|
||||
</EmptyStateContainer>
|
||||
);
|
||||
const v2Flag = checkForFlag(API_PANE_V2);
|
||||
const homeScreen = v2Flag ? apiHomeScreen : defaultHomeScreen;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{apiId ? (
|
||||
|
|
@ -183,12 +208,7 @@ class ApiEditor extends React.Component<Props> {
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
<ApiHomeScreen
|
||||
applicationId={this.props.match.params.applicationId}
|
||||
pageId={this.props.match.params.pageId}
|
||||
history={this.props.history}
|
||||
location={this.props.location}
|
||||
/>
|
||||
homeScreen
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ import {
|
|||
copyActionRequest,
|
||||
deleteAction,
|
||||
} from "actions/actionActions";
|
||||
import { changeApi, initApiPane } from "actions/apiPaneActions";
|
||||
import {
|
||||
changeApi,
|
||||
createNewApiAction,
|
||||
initApiPane,
|
||||
} from "actions/apiPaneActions";
|
||||
import { RestAction } from "api/ActionAPI";
|
||||
import { getPluginIdOfName } from "selectors/entitiesSelector";
|
||||
import { PLUGIN_NAME } from "constants/ApiEditorConstants";
|
||||
|
|
@ -20,6 +24,7 @@ import EditorSidebar from "pages/Editor/EditorSidebar";
|
|||
import { getNextEntityName } from "utils/AppsmithUtils";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import { API_EDITOR_URL_WITH_SELECTED_PAGE_ID } from "constants/routes";
|
||||
import { API_PANE_V2, checkForFlag } from "utils/featureFlags";
|
||||
|
||||
const HTTPMethod = styled.span<{ method?: string }>`
|
||||
flex: 1;
|
||||
|
|
@ -73,6 +78,7 @@ interface ReduxDispatchProps {
|
|||
) => void;
|
||||
copyAction: (id: string, pageId: string, name: string) => void;
|
||||
deleteAction: (id: string, name: string) => void;
|
||||
createNewApiAction: (pageId: string) => void;
|
||||
}
|
||||
|
||||
type Props = ReduxStateProps &
|
||||
|
|
@ -159,15 +165,20 @@ class ApiSidebar extends React.Component<Props> {
|
|||
};
|
||||
|
||||
handleCreateNewApiClick = (selectedPageId: string) => {
|
||||
const { history } = this.props;
|
||||
const { history, createNewApiAction } = this.props;
|
||||
const { pageId, applicationId } = this.props.match.params;
|
||||
history.push(
|
||||
API_EDITOR_URL_WITH_SELECTED_PAGE_ID(
|
||||
applicationId,
|
||||
pageId,
|
||||
selectedPageId,
|
||||
),
|
||||
);
|
||||
const v2Flag = checkForFlag(API_PANE_V2);
|
||||
if (v2Flag) {
|
||||
history.push(
|
||||
API_EDITOR_URL_WITH_SELECTED_PAGE_ID(
|
||||
applicationId,
|
||||
pageId,
|
||||
selectedPageId,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
createNewApiAction(selectedPageId);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
@ -223,6 +234,7 @@ const mapDispatchToProps = (dispatch: Function): ReduxDispatchProps => ({
|
|||
dispatch(copyActionRequest({ id, destinationPageId, name })),
|
||||
deleteAction: (id: string, name: string) =>
|
||||
dispatch(deleteAction({ id, name })),
|
||||
createNewApiAction: (pageId: string) => dispatch(createNewApiAction(pageId)),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ApiSidebar);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@ import {
|
|||
} from "constants/ReduxActionConstants";
|
||||
import { getFormData } from "selectors/formSelectors";
|
||||
import { API_EDITOR_FORM_NAME, API_HOME_SCREEN_FORM } from "constants/forms";
|
||||
import { POST_BODY_FORMAT_OPTIONS } from "constants/ApiEditorConstants";
|
||||
import {
|
||||
DEFAULT_API_ACTION,
|
||||
POST_BODY_FORMAT_OPTIONS,
|
||||
REST_PLUGIN_PACKAGE_NAME,
|
||||
} from "constants/ApiEditorConstants";
|
||||
import history from "utils/history";
|
||||
import { API_EDITOR_ID_URL, API_EDITOR_URL } from "constants/routes";
|
||||
import {
|
||||
|
|
@ -31,6 +35,11 @@ import {
|
|||
VALID_FUNCTION_NAME_ERROR,
|
||||
} from "constants/messages";
|
||||
import { fetchProvidersWithCategory } from "actions/providerActions";
|
||||
import { createNewApiName } from "utils/AppsmithUtils";
|
||||
import { getPluginIdOfPackageName } from "sagas/selectors";
|
||||
import { getActions } from "selectors/entitiesSelector";
|
||||
import { ActionData } from "reducers/entityReducers/actionsReducer";
|
||||
import { createActionRequest } from "actions/actionActions";
|
||||
|
||||
const getApiDraft = (state: AppState, id: string) => {
|
||||
const drafts = state.ui.apiPane.drafts;
|
||||
|
|
@ -38,7 +47,7 @@ const getApiDraft = (state: AppState, id: string) => {
|
|||
return {};
|
||||
};
|
||||
|
||||
const getActions = (state: AppState) =>
|
||||
const getActionConfigs = (state: AppState): ActionData["config"][] =>
|
||||
state.entities.actions.map(a => a.config);
|
||||
|
||||
const getLastUsedAction = (state: AppState) => state.ui.apiPane.lastUsed;
|
||||
|
|
@ -234,7 +243,7 @@ function* validateInputSaga(
|
|||
payload,
|
||||
meta: { field },
|
||||
} = actionPayload;
|
||||
const actions: RestAction[] = yield select(getActions);
|
||||
const actions: RestAction[] = yield select(getActionConfigs);
|
||||
const sameNames = actions.filter(
|
||||
(action: RestAction) => action.name === payload && action.id,
|
||||
);
|
||||
|
|
@ -375,6 +384,34 @@ function* handleMoveOrCopySaga(actionPayload: ReduxAction<{ id: string }>) {
|
|||
}
|
||||
}
|
||||
|
||||
function* handleCreateNewApiActionSaga(
|
||||
action: ReduxAction<{ pageId: string }>,
|
||||
) {
|
||||
const pluginId = yield select(
|
||||
getPluginIdOfPackageName,
|
||||
REST_PLUGIN_PACKAGE_NAME,
|
||||
);
|
||||
const { pageId } = action.payload;
|
||||
if (pageId && pluginId) {
|
||||
const actions = yield select(getActions);
|
||||
const pageActions = actions.filter(
|
||||
(a: ActionData) => a.config.pageId === pageId,
|
||||
);
|
||||
const newActionName = createNewApiName(pageActions, pageId);
|
||||
yield put(
|
||||
createActionRequest({
|
||||
...DEFAULT_API_ACTION,
|
||||
name: newActionName,
|
||||
datasource: {
|
||||
name: "DEFAULT_REST_DATASOURCE",
|
||||
pluginId,
|
||||
},
|
||||
pageId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default function* root() {
|
||||
yield all([
|
||||
takeEvery(ReduxActionTypes.INIT_API_PANE, initApiPaneSaga),
|
||||
|
|
@ -384,6 +421,10 @@ export default function* root() {
|
|||
takeEvery(ReduxActionTypes.DELETE_ACTION_SUCCESS, handleActionDeletedSaga),
|
||||
takeEvery(ReduxActionTypes.MOVE_ACTION_SUCCESS, handleMoveOrCopySaga),
|
||||
takeEvery(ReduxActionTypes.COPY_ACTION_SUCCESS, handleMoveOrCopySaga),
|
||||
takeEvery(
|
||||
ReduxActionTypes.CREATE_NEW_API_ACTION,
|
||||
handleCreateNewApiActionSaga,
|
||||
),
|
||||
// Intercepting the redux-form change actionType
|
||||
takeEvery(ReduxFormActionTypes.VALUE_CHANGE, formValueChangeSaga),
|
||||
takeEvery(ReduxFormActionTypes.ARRAY_REMOVE, formValueChangeSaga),
|
||||
|
|
|
|||
|
|
@ -74,3 +74,13 @@ export const getWidgetByName = (
|
|||
widget => widget.widgetName === widgetName,
|
||||
);
|
||||
};
|
||||
|
||||
export const getPluginIdOfPackageName = (
|
||||
state: AppState,
|
||||
name: string,
|
||||
): string | undefined => {
|
||||
const plugins = state.entities.plugins.list;
|
||||
const plugin = _.find(plugins, { packageName: name });
|
||||
if (plugin) return plugin.id;
|
||||
return undefined;
|
||||
};
|
||||
|
|
|
|||
5
app/client/src/utils/featureFlags.ts
Normal file
5
app/client/src/utils/featureFlags.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export const API_PANE_V2 = "ApiPaneV2";
|
||||
|
||||
export const checkForFlag = (flagName: string) => {
|
||||
return localStorage.getItem(flagName);
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user