import React from "react"; import { connect } from "react-redux"; import { RouteComponentProps } from "react-router"; import styled from "styled-components"; import { AppState } from "reducers"; import { ActionDataState } from "reducers/entityReducers/actionsReducer"; import { APIEditorRouteParams } from "constants/routes"; import { ApiPaneReduxState } from "reducers/uiReducers/apiPaneReducer"; import { createActionRequest, moveActionRequest, copyActionRequest, deleteAction, } from "actions/actionActions"; import { changeApi, createNewApiAction, initApiPane, } from "actions/apiPaneActions"; import { RestAction } from "api/ActionAPI"; import { getPluginIdOfName } from "selectors/entitiesSelector"; import { PLUGIN_NAME } from "constants/ApiEditorConstants"; 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; font-size: 12px; color: ${props => { switch (props.method) { case "GET": return "#29CCA3"; case "POST": return "#F7C75B"; case "PUT": return "#30A5E0"; case "PATCH": return "#8E8E8E"; case "DELETE": return "#CE4257"; default: return "#333"; } }}; `; const ActionItem = styled.div` flex: 1; display: flex; align-items: center; `; const ActionName = styled.span` flex: 3; padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100px; `; interface ReduxStateProps { actions: ActionDataState; apiPane: ApiPaneReduxState; pluginId: string | undefined; } interface ReduxDispatchProps { createAction: (data: Partial) => void; onApiChange: (id: string) => void; initApiPane: (urlId?: string) => void; moveAction: ( id: string, pageId: string, name: string, originalPageId: string, ) => void; copyAction: (id: string, pageId: string, name: string) => void; deleteAction: (id: string, name: string) => void; createNewApiAction: (pageId: string) => void; } type Props = ReduxStateProps & ReduxDispatchProps & RouteComponentProps; class ApiSidebar extends React.Component { componentDidMount(): void { this.props.initApiPane(this.props.match.params.apiId); } shouldComponentUpdate(nextProps: Readonly): boolean { if ( Object.keys(nextProps.apiPane.drafts) !== Object.keys(this.props.apiPane.drafts) ) { return true; } return nextProps.actions !== this.props.actions; } handleApiChange = (actionId: string) => { this.props.onApiChange(actionId); }; handleMove = (itemId: string, destinationPageId: string) => { const action = this.props.actions.filter(a => a.config.id === itemId)[0]; const pageApiNames = this.props.actions .filter(a => a.config.pageId === destinationPageId) .map(a => a.config.name); let name = action.config.name; if (pageApiNames.indexOf(action.config.name) > -1) { name = getNextEntityName(name, pageApiNames); } this.props.moveAction( itemId, destinationPageId, name, action.config.pageId, ); }; handleCopy = (itemId: string, destinationPageId: string) => { const action = this.props.actions.filter(a => a.config.id === itemId)[0]; const pageApiNames = this.props.actions .filter(a => a.config.pageId === destinationPageId) .map(a => a.config.name); let name = `${action.config.name}Copy`; if (pageApiNames.indexOf(name) > -1) { name = getNextEntityName(name, pageApiNames); } this.props.copyAction(itemId, destinationPageId, name); }; handleDelete = (itemId: string, itemName: string, pageName: string) => { AnalyticsUtil.logEvent("DELETE_API_CLICK", { apiId: itemId, apiName: itemName, pageName: pageName, }); this.props.deleteAction(itemId, itemName); }; renderItem = (action: RestAction) => { return ( { AnalyticsUtil.logEvent("API_SELECT", { apiId: action.id, apiName: action.name, }); }} > {action.actionConfiguration ? ( {action.actionConfiguration.httpMethod} ) : ( )} {action.name} ); }; handleCreateNewApiClick = (selectedPageId: string) => { const { history, createNewApiAction } = this.props; const { pageId, applicationId } = this.props.match.params; const v2Flag = checkForFlag(API_PANE_V2); if (v2Flag) { history.push( API_EDITOR_URL_WITH_SELECTED_PAGE_ID( applicationId, pageId, selectedPageId, ), ); } else { createNewApiAction(selectedPageId); } }; render() { const { apiPane: { isFetching, drafts }, match: { params: { apiId }, }, actions, pluginId, } = this.props; if (!pluginId) return null; const data = actions.map(a => a.config); return ( ); } } const mapStateToProps = (state: AppState): ReduxStateProps => ({ pluginId: getPluginIdOfName(state, PLUGIN_NAME), actions: state.entities.actions, apiPane: state.ui.apiPane, }); const mapDispatchToProps = (dispatch: Function): ReduxDispatchProps => ({ createAction: (data: Partial) => dispatch(createActionRequest(data)), onApiChange: (actionId: string) => dispatch(changeApi(actionId)), initApiPane: (urlId?: string) => dispatch(initApiPane(urlId)), moveAction: ( id: string, destinationPageId: string, name: string, originalPageId: string, ) => dispatch( moveActionRequest({ id, destinationPageId, originalPageId, name }), ), copyAction: (id: string, destinationPageId: string, name: string) => 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);