Merge branch 'release' of gitlab.com:theappsmith/internal-tools-client into feature/js-executor
This commit is contained in:
commit
2ac28cde5b
|
|
@ -83,7 +83,7 @@
|
|||
"build": "craco build",
|
||||
"test": "craco test",
|
||||
"eject": "react-scripts eject",
|
||||
"flow": "flow"
|
||||
"start-prod": "REACT_APP_ENVIRONMENT=PRODUCTION craco start"
|
||||
},
|
||||
"resolution": {
|
||||
"jest": "24.8.0"
|
||||
|
|
|
|||
8
app/client/src/actions/pluginActions.ts
Normal file
8
app/client/src/actions/pluginActions.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxActionWithoutPayload,
|
||||
} from "constants/ReduxActionConstants";
|
||||
|
||||
export const fetchPlugins = (): ReduxActionWithoutPayload => ({
|
||||
type: ReduxActionTypes.FETCH_PLUGINS_REQUEST,
|
||||
});
|
||||
18
app/client/src/api/PluginApi.ts
Normal file
18
app/client/src/api/PluginApi.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import Api from "./Api";
|
||||
import { AxiosPromise } from "axios";
|
||||
import { GenericApiResponse } from "api/ApiResponses";
|
||||
|
||||
export interface Plugin {
|
||||
id: string;
|
||||
name: string;
|
||||
type: "API" | "DB";
|
||||
}
|
||||
|
||||
class PluginsApi extends Api {
|
||||
static url = "v1/plugins";
|
||||
static fetchPlugins(): AxiosPromise<GenericApiResponse<Plugin[]>> {
|
||||
return Api.get(PluginsApi.url);
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginsApi;
|
||||
|
|
@ -4,14 +4,15 @@ import styled, { css } from "styled-components";
|
|||
import { TextComponentProps } from "./TextComponent";
|
||||
import { ButtonStyle } from "widgets/ButtonWidget";
|
||||
import { Theme } from "constants/DefaultTheme";
|
||||
import _ from "lodash";
|
||||
|
||||
const getButtonColorStyles = (props: { theme: Theme } & ButtonStyleProps) => {
|
||||
if (props.filled) return props.theme.colors.textOnDarkBG;
|
||||
if (props.styleName) {
|
||||
if (props.styleName === "secondary") {
|
||||
if (props.accent) {
|
||||
if (props.accent === "secondary") {
|
||||
return props.theme.colors.OXFORD_BLUE;
|
||||
}
|
||||
return props.theme.colors[props.styleName];
|
||||
return props.theme.colors[props.accent];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -22,18 +23,20 @@ const ButtonColorStyles = css<ButtonStyleProps>`
|
|||
}
|
||||
`;
|
||||
|
||||
const ButtonWrapper = styled(AnchorButton)<ButtonStyleProps>`
|
||||
const ButtonWrapper = styled((props: ButtonStyleProps & IButtonProps) => (
|
||||
<AnchorButton {..._.omit(props, ["accent", "filled"])} />
|
||||
))<ButtonStyleProps>`
|
||||
&& {
|
||||
${ButtonColorStyles};
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: background-color 0.2s;
|
||||
background-color: ${props =>
|
||||
props.filled && props.styleName && props.theme.colors[props.styleName]};
|
||||
props.filled && props.accent && props.theme.colors[props.accent]};
|
||||
border: 1px solid
|
||||
${props =>
|
||||
props.styleName
|
||||
? props.theme.colors[props.styleName]
|
||||
props.accent
|
||||
? props.theme.colors[props.accent]
|
||||
: props.theme.colors.secondary};
|
||||
border-radius: 4px;
|
||||
font-weight: ${props => props.theme.fontWeights[2]};
|
||||
|
|
@ -44,14 +47,14 @@ const ButtonWrapper = styled(AnchorButton)<ButtonStyleProps>`
|
|||
${ButtonColorStyles};
|
||||
background-color: ${props => {
|
||||
if (!props.filled) return props.theme.colors.secondaryDarker;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darker`];
|
||||
if (props.accent !== "secondary") {
|
||||
return props.theme.colors[`${props.accent}Darker`];
|
||||
}
|
||||
}};
|
||||
border-color: ${props => {
|
||||
if (!props.filled) return;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darker`];
|
||||
if (props.accent !== "secondary") {
|
||||
return props.theme.colors[`${props.accent}Darker`];
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
@ -59,14 +62,14 @@ const ButtonWrapper = styled(AnchorButton)<ButtonStyleProps>`
|
|||
${ButtonColorStyles};
|
||||
background-color: ${props => {
|
||||
if (!props.filled) return props.theme.colors.secondaryDarkest;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darkest`];
|
||||
if (props.accent !== "secondary") {
|
||||
return props.theme.colors[`${props.accent}Darkest`];
|
||||
}
|
||||
}};
|
||||
border-color: ${props => {
|
||||
if (!props.filled) return;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darkest`];
|
||||
if (props.accent !== "secondary") {
|
||||
return props.theme.colors[`${props.accent}Darkest`];
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
@ -79,7 +82,7 @@ const ButtonWrapper = styled(AnchorButton)<ButtonStyleProps>`
|
|||
export type ButtonStyleName = "primary" | "secondary" | "error";
|
||||
|
||||
type ButtonStyleProps = {
|
||||
styleName?: ButtonStyleName;
|
||||
accent?: ButtonStyleName;
|
||||
filled?: boolean;
|
||||
};
|
||||
|
||||
|
|
@ -89,7 +92,7 @@ export const BaseButton = (props: IButtonProps & ButtonStyleProps) => {
|
|||
};
|
||||
|
||||
BaseButton.defaultProps = {
|
||||
styleName: "secondary",
|
||||
accent: "secondary",
|
||||
disabled: false,
|
||||
text: "Button Text",
|
||||
minimal: true,
|
||||
|
|
@ -122,7 +125,7 @@ const ButtonContainer = (props: ButtonContainerProps & ButtonStyleProps) => {
|
|||
icon={props.icon}
|
||||
text={props.text}
|
||||
filled={props.buttonStyle === "PRIMARY_BUTTON"}
|
||||
styleName={mapButtonStyleToStyleName(props.buttonStyle)}
|
||||
accent={mapButtonStyleToStyleName(props.buttonStyle)}
|
||||
onClick={props.onClick}
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { ComponentProps } from "components/designSystems/appsmith/BaseComponent"
|
|||
import { TextStyle } from "widgets/TextWidget";
|
||||
|
||||
type TextStyleProps = {
|
||||
styleName: "primary" | "secondary" | "error";
|
||||
accent: "primary" | "secondary" | "error";
|
||||
};
|
||||
|
||||
export const BaseText = styled(Text)<TextStyleProps>``;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ const ApiResponseView = (props: Props) => {
|
|||
<React.Fragment>
|
||||
{response.statusCode && (
|
||||
<StatusCodeText
|
||||
styleName="secondary"
|
||||
accent="secondary"
|
||||
code={response.statusCode.toString()}
|
||||
>
|
||||
Status: {response.statusCode}
|
||||
|
|
@ -128,12 +128,12 @@ const ApiResponseView = (props: Props) => {
|
|||
)}
|
||||
<ResponseMetaInfo>
|
||||
{response.duration && (
|
||||
<BaseText styleName="secondary">
|
||||
<BaseText accent="secondary">
|
||||
Time: {response.duration} ms
|
||||
</BaseText>
|
||||
)}
|
||||
{response.size && (
|
||||
<BaseText styleName="secondary">
|
||||
<BaseText accent="secondary">
|
||||
Size: {formatBytes(parseInt(response.size))}
|
||||
</BaseText>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class DropdownComponent extends Component<DropdownComponentProps> {
|
|||
const displayMode = (
|
||||
<BaseButton
|
||||
icon-right="plus"
|
||||
styleName="primary"
|
||||
accent="primary"
|
||||
filled={true}
|
||||
text={this.props.addItem.displayText}
|
||||
onClick={this.showTextBox}
|
||||
|
|
@ -130,7 +130,7 @@ class DropdownComponent extends Component<DropdownComponentProps> {
|
|||
>
|
||||
{this.props.toggle || (
|
||||
<BaseButton
|
||||
styleName="secondary"
|
||||
accent="secondary"
|
||||
text={this.getSelectedDisplayText()}
|
||||
rightIcon="chevron-down"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import { AppState } from "reducers";
|
|||
import { DatasourceDataState } from "reducers/entityReducers/datasourceReducer";
|
||||
import _ from "lodash";
|
||||
import { createDatasource } from "actions/datasourcesActions";
|
||||
import { REST_PLUGIN_ID } from "constants/ApiEditorConstants";
|
||||
|
||||
interface ReduxStateProps {
|
||||
datasources: DatasourceDataState;
|
||||
|
|
@ -17,12 +16,14 @@ interface ReduxActionProps {
|
|||
|
||||
interface ComponentProps {
|
||||
name: string;
|
||||
pluginId: string;
|
||||
}
|
||||
|
||||
const DatasourcesField = (
|
||||
props: ReduxActionProps & ReduxStateProps & ComponentProps,
|
||||
) => {
|
||||
const options = props.datasources.list
|
||||
.filter(r => r.pluginId === props.pluginId)
|
||||
.filter(r => r.datasourceConfiguration !== null)
|
||||
.map(r => ({
|
||||
label: r.datasourceConfiguration.url.endsWith("/")
|
||||
|
|
@ -49,7 +50,10 @@ const mapStateToProps = (state: AppState): ReduxStateProps => ({
|
|||
datasources: state.entities.datasources,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: any): ReduxActionProps => ({
|
||||
const mapDispatchToProps = (
|
||||
dispatch: any,
|
||||
ownProps: ComponentProps,
|
||||
): ReduxActionProps => ({
|
||||
createDatasource: (value: string) =>
|
||||
dispatch(
|
||||
createDatasource({
|
||||
|
|
@ -59,7 +63,7 @@ const mapDispatchToProps = (dispatch: any): ReduxActionProps => ({
|
|||
// Datasource url should end with /
|
||||
url: value.endsWith("/") ? value : `${value}/`,
|
||||
},
|
||||
pluginId: REST_PLUGIN_ID,
|
||||
pluginId: ownProps.pluginId,
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -31,4 +31,4 @@ export const FORM_INITIAL_VALUES = {
|
|||
},
|
||||
};
|
||||
|
||||
export const REST_PLUGIN_ID = "5ca385dc81b37f0004b4db85";
|
||||
export const PLUGIN_NAME = "RestTemplatePluginExecutor";
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ export const ReduxActionTypes: { [key: string]: string } = {
|
|||
UPDATE_API_DRAFT: "UPDATE_API_DRAFT",
|
||||
DELETE_API_DRAFT: "DELETE_API_DRAFT",
|
||||
UPDATE_ROUTES_PARAMS: "UPDATE_ROUTES_PARAMS",
|
||||
FETCH_PLUGINS_REQUEST: "FETCH_PLUGINS_REQUEST",
|
||||
FETCH_PLUGINS_SUCCESS: "FETCH_PLUGINS_SUCCESS",
|
||||
};
|
||||
|
||||
export type ReduxActionType = typeof ReduxActionTypes[keyof typeof ReduxActionTypes];
|
||||
|
|
@ -122,6 +124,7 @@ export const ReduxActionErrorTypes: { [key: string]: string } = {
|
|||
FETCH_APPLICATION_LIST_ERROR: "FETCH_APPLICATION_LIST_ERROR",
|
||||
CREATE_APPLICATION_ERROR: "CREATE_APPLICATION_ERROR",
|
||||
SAVE_JS_EXECUTION_RECORD: "SAVE_JS_EXECUTION_RECORD",
|
||||
FETCH_PLUGINS_ERROR: "FETCH_PLUGINS_ERROR",
|
||||
};
|
||||
|
||||
export const ReduxFormActionTypes: { [key: string]: string } = {
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ export const ApplicationCard = (props: ApplicationCardProps) => {
|
|||
<BaseButton
|
||||
icon="edit"
|
||||
text="Edit"
|
||||
styleName="primary"
|
||||
accent="primary"
|
||||
filled={true}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ const JSONEditorFieldWrapper = styled.div`
|
|||
`;
|
||||
|
||||
interface APIFormProps {
|
||||
pluginId: string;
|
||||
allowSave: boolean;
|
||||
allowPostBody: boolean;
|
||||
onSubmit: FormSubmitHandler<RestAction>;
|
||||
|
|
@ -84,6 +85,7 @@ type Props = APIFormProps & InjectedFormProps<RestAction, APIFormProps>;
|
|||
|
||||
const ApiEditorForm: React.FC<Props> = (props: Props) => {
|
||||
const {
|
||||
pluginId,
|
||||
allowSave,
|
||||
allowPostBody,
|
||||
onSaveClick,
|
||||
|
|
@ -102,19 +104,19 @@ const ApiEditorForm: React.FC<Props> = (props: Props) => {
|
|||
<ActionButtons>
|
||||
<ActionButton
|
||||
text="Delete"
|
||||
styleName="error"
|
||||
accent="error"
|
||||
onClick={onDeleteClick}
|
||||
loading={isDeleting}
|
||||
/>
|
||||
<ActionButton
|
||||
text="Run"
|
||||
styleName="secondary"
|
||||
accent="secondary"
|
||||
onClick={onRunClick}
|
||||
loading={isRunning}
|
||||
/>
|
||||
<ActionButton
|
||||
text="Save"
|
||||
styleName="primary"
|
||||
accent="primary"
|
||||
filled
|
||||
onClick={onSaveClick}
|
||||
loading={isSaving}
|
||||
|
|
@ -128,7 +130,7 @@ const ApiEditorForm: React.FC<Props> = (props: Props) => {
|
|||
name="actionConfiguration.httpMethod"
|
||||
options={HTTP_METHOD_OPTIONS}
|
||||
/>
|
||||
<DatasourcesField name="datasource.id" />
|
||||
<DatasourcesField name="datasource.id" pluginId={pluginId} />
|
||||
<TextField
|
||||
placeholder="API Path"
|
||||
name="actionConfiguration.path"
|
||||
|
|
|
|||
|
|
@ -15,13 +15,15 @@ import { API_EDITOR_FORM_NAME } from "constants/forms";
|
|||
import { ActionDataState } from "reducers/entityReducers/actionsReducer";
|
||||
import { ApiPaneReduxState } from "reducers/uiReducers/apiPaneReducer";
|
||||
import styled from "styled-components";
|
||||
import { HTTP_METHODS } from "constants/ApiEditorConstants";
|
||||
import { HTTP_METHODS, PLUGIN_NAME } from "constants/ApiEditorConstants";
|
||||
import _ from "lodash";
|
||||
import { getPluginIdOfName } from "selectors/entitiesSelector";
|
||||
|
||||
interface ReduxStateProps {
|
||||
actions: ActionDataState;
|
||||
apiPane: ApiPaneReduxState;
|
||||
formData: RestAction;
|
||||
pluginId: string | undefined;
|
||||
}
|
||||
interface ReduxActionProps {
|
||||
submitForm: (name: string) => void;
|
||||
|
|
@ -70,12 +72,19 @@ class ApiEditor extends React.Component<Props> {
|
|||
params: { apiId },
|
||||
},
|
||||
formData,
|
||||
pluginId,
|
||||
} = this.props;
|
||||
const httpMethod = _.get(formData, "actionConfiguration.httpMethod");
|
||||
if (!pluginId) {
|
||||
return (
|
||||
<EmptyStateContainer>{"Plugin is not installed"}</EmptyStateContainer>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<React.Fragment>
|
||||
{apiId ? (
|
||||
<ApiEditorForm
|
||||
pluginId={pluginId}
|
||||
allowSave={apiId in drafts}
|
||||
allowPostBody={httpMethod && httpMethod !== HTTP_METHODS[0]}
|
||||
isSaving={isSaving}
|
||||
|
|
@ -97,6 +106,7 @@ class ApiEditor extends React.Component<Props> {
|
|||
}
|
||||
|
||||
const mapStateToProps = (state: AppState): ReduxStateProps => ({
|
||||
pluginId: getPluginIdOfName(state, PLUGIN_NAME),
|
||||
actions: state.entities.actions,
|
||||
apiPane: state.ui.apiPane,
|
||||
formData: getFormValues(API_EDITOR_FORM_NAME)(state) as RestAction,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ import { changeApi, initApiPane } from "actions/apiPaneActions";
|
|||
import { RestAction } from "api/ActionAPI";
|
||||
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
|
||||
import Fuse from "fuse.js";
|
||||
import { getPluginIdOfName } from "selectors/entitiesSelector";
|
||||
import { PLUGIN_NAME } from "constants/ApiEditorConstants";
|
||||
|
||||
const LoadingContainer = styled(CenteredWrapper)`
|
||||
height: 50%;
|
||||
|
|
@ -133,6 +135,7 @@ const CreateApiWrapper = styled.div`
|
|||
interface ReduxStateProps {
|
||||
actions: ActionDataState;
|
||||
apiPane: ApiPaneReduxState;
|
||||
pluginId: string | undefined;
|
||||
}
|
||||
|
||||
interface ReduxDispatchProps {
|
||||
|
|
@ -226,7 +229,9 @@ class ApiSidebar extends React.Component<Props, State> {
|
|||
apiPane: { isFetching, isSaving, drafts },
|
||||
match,
|
||||
actions: { data },
|
||||
pluginId,
|
||||
} = this.props;
|
||||
if (!pluginId) return null;
|
||||
const { isCreating, search, name } = this.state;
|
||||
const activeActionId = match.params.apiId;
|
||||
const fuse = new Fuse(data, fuseOptions);
|
||||
|
|
@ -277,7 +282,7 @@ class ApiSidebar extends React.Component<Props, State> {
|
|||
/>
|
||||
<BaseButton
|
||||
icon={TICK}
|
||||
styleName="primary"
|
||||
accent="primary"
|
||||
text=""
|
||||
onClick={this.saveAction}
|
||||
filled
|
||||
|
|
@ -303,6 +308,7 @@ class ApiSidebar extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
const mapStateToProps = (state: AppState): ReduxStateProps => ({
|
||||
pluginId: getPluginIdOfName(state, PLUGIN_NAME),
|
||||
actions: state.entities.actions,
|
||||
apiPane: state.ui.apiPane,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export const EditorHeader = (props: EditorHeaderProps) => {
|
|||
onClick={props.onPublish}
|
||||
text="Publish"
|
||||
loading={props.isPublishing}
|
||||
styleName="primary"
|
||||
accent="primary"
|
||||
filled
|
||||
/>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { createReducer } from "utils/AppsmithUtils";
|
||||
import { ReduxActionTypes, ReduxAction } from "constants/ReduxActionConstants";
|
||||
import { Datasource } from "api/DatasourcesApi";
|
||||
import { REST_PLUGIN_ID } from "constants/ApiEditorConstants";
|
||||
|
||||
export interface DatasourceDataState {
|
||||
list: Datasource[];
|
||||
|
|
@ -27,8 +26,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
// TODO(hetu) Once plugins are being pulled get Ids from there
|
||||
list: action.payload.filter(r => r.pluginId === REST_PLUGIN_ID),
|
||||
list: action.payload,
|
||||
};
|
||||
},
|
||||
[ReduxActionTypes.CREATE_DATASOURCE_SUCCESS]: (
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import datasourceReducer from "./datasourceReducer";
|
|||
import bindingsReducer from "./bindingsReducer";
|
||||
import pageListReducer from "./pageListReducer";
|
||||
import jsExecutionsReducer from "./jsExecutionsReducer";
|
||||
import pluginsReducer from "reducers/entityReducers/pluginsReducer";
|
||||
|
||||
const entityReducer = combineReducers({
|
||||
canvasWidgets: canvasWidgetsReducer,
|
||||
|
|
@ -21,6 +22,7 @@ const entityReducer = combineReducers({
|
|||
nameBindings: bindingsReducer,
|
||||
pageList: pageListReducer,
|
||||
jsExecutions: jsExecutionsReducer,
|
||||
plugins: pluginsReducer,
|
||||
});
|
||||
|
||||
export default entityReducer;
|
||||
|
|
|
|||
37
app/client/src/reducers/entityReducers/pluginsReducer.ts
Normal file
37
app/client/src/reducers/entityReducers/pluginsReducer.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { createReducer } from "utils/AppsmithUtils";
|
||||
import { ReduxActionTypes, ReduxAction } from "constants/ReduxActionConstants";
|
||||
import { Plugin } from "api/PluginApi";
|
||||
|
||||
export interface PluginDataState {
|
||||
list: Plugin[];
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const initialState: PluginDataState = {
|
||||
list: [],
|
||||
loading: false,
|
||||
};
|
||||
|
||||
const pluginsReducer = createReducer(initialState, {
|
||||
[ReduxActionTypes.FETCH_PLUGINS_REQUEST]: (state: PluginDataState) => {
|
||||
return { ...state, loading: true };
|
||||
},
|
||||
[ReduxActionTypes.FETCH_PLUGINS_SUCCESS]: (
|
||||
state: PluginDataState,
|
||||
action: ReduxAction<Plugin[]>,
|
||||
) => {
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
list: action.payload,
|
||||
};
|
||||
},
|
||||
[ReduxActionTypes.FETCH_PLUGINS_ERROR]: (state: PluginDataState) => {
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default pluginsReducer;
|
||||
|
|
@ -19,6 +19,7 @@ import { BindingsDataState } from "./entityReducers/bindingsReducer";
|
|||
import { PageListReduxState } from "./entityReducers/pageListReducer";
|
||||
import { ApiPaneReduxState } from "./uiReducers/apiPaneReducer";
|
||||
import { RoutesParamsReducerState } from "reducers/uiReducers/routesParamsReducer";
|
||||
import { PluginDataState } from "reducers/entityReducers/pluginsReducer";
|
||||
|
||||
const appReducer = combineReducers({
|
||||
entities: entityReducer,
|
||||
|
|
@ -49,6 +50,7 @@ export interface AppState {
|
|||
datasources: DatasourceDataState;
|
||||
nameBindings: BindingsDataState;
|
||||
pageList: PageListReduxState;
|
||||
plugins: PluginDataState;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { fetchPageList } from "actions/pageActions";
|
|||
import { fetchActions } from "actions/actionActions";
|
||||
import { fetchDatasources } from "actions/datasourcesActions";
|
||||
import { initBindingMapListener } from "actions/bindingActions";
|
||||
import { fetchPlugins } from "actions/pluginActions";
|
||||
|
||||
function* initializeEditorSaga(
|
||||
initializeEditorAction: ReduxAction<InitializeEditorPayload>,
|
||||
|
|
@ -17,6 +18,7 @@ function* initializeEditorSaga(
|
|||
const { applicationId } = initializeEditorAction.payload;
|
||||
// Step 1: Start getting all the data needed by the
|
||||
yield all([
|
||||
put(fetchPlugins()),
|
||||
put(fetchPageList(applicationId)),
|
||||
put(fetchEditorConfigs()),
|
||||
put(initBindingMapListener()),
|
||||
|
|
@ -25,6 +27,7 @@ function* initializeEditorSaga(
|
|||
]);
|
||||
// Step 2: Wait for all data to be in the state
|
||||
yield all([
|
||||
take(ReduxActionTypes.FETCH_PLUGINS_SUCCESS),
|
||||
take(ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS),
|
||||
take(ReduxActionTypes.FETCH_ACTIONS_SUCCESS),
|
||||
take(ReduxActionTypes.FETCH_DATASOURCES_SUCCESS),
|
||||
|
|
|
|||
30
app/client/src/sagas/PluginSagas.ts
Normal file
30
app/client/src/sagas/PluginSagas.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { all, takeEvery, call, put } from "redux-saga/effects";
|
||||
import { ReduxActionTypes } from "constants/ReduxActionConstants";
|
||||
import PluginsApi from "api/PluginApi";
|
||||
import { validateResponse } from "sagas/ErrorSagas";
|
||||
|
||||
function* fetchPluginsSaga() {
|
||||
try {
|
||||
const pluginsResponse = yield call(PluginsApi.fetchPlugins);
|
||||
const isValid = yield validateResponse(pluginsResponse);
|
||||
if (isValid) {
|
||||
yield put({
|
||||
type: ReduxActionTypes.FETCH_PLUGINS_SUCCESS,
|
||||
payload: pluginsResponse.data,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
yield put({
|
||||
type: ReduxActionTypes.FETCH_PLUGINS_ERROR,
|
||||
payload: { error },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function* root() {
|
||||
yield all([
|
||||
takeEvery(ReduxActionTypes.FETCH_PLUGINS_REQUEST, fetchPluginsSaga),
|
||||
]);
|
||||
}
|
||||
|
||||
export default root;
|
||||
|
|
@ -13,6 +13,7 @@ import watchActionWidgetMapSagas, {
|
|||
watchPropertyAndBindingUpdate,
|
||||
} from "./ActionWidgetMapSagas";
|
||||
import apiPaneSagas from "./ApiPaneSagas";
|
||||
import pluginSagas from "./PluginSagas";
|
||||
|
||||
export function* rootSaga() {
|
||||
yield all([
|
||||
|
|
@ -29,5 +30,6 @@ export function* rootSaga() {
|
|||
spawn(watchActionWidgetMapSagas),
|
||||
spawn(watchPropertyAndBindingUpdate),
|
||||
spawn(apiPaneSagas),
|
||||
spawn(pluginSagas),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,14 @@
|
|||
import { AppState, DataTree } from "reducers";
|
||||
|
||||
export const getDataTree = (state: AppState): DataTree => state.entities;
|
||||
|
||||
export const getPluginIdOfName = (
|
||||
state: AppState,
|
||||
name: string,
|
||||
): string | undefined => {
|
||||
const plugin = state.entities.plugins.list.find(
|
||||
plugin => plugin.name === name,
|
||||
);
|
||||
if (!plugin) return undefined;
|
||||
return plugin.id;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user