API form
This commit is contained in:
parent
618ede4ffb
commit
e0348cc1f3
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"src/**/*.tsx": ["npx eslint --fix", "npx prettier --write", "git add"]
|
||||
"src/**/*.tsx": ["npx eslint --fix", "npx prettier --write", "git add"],
|
||||
"src/**/*.ts": ["npx eslint --fix", "npx prettier --write", "git add"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,17 +42,22 @@
|
|||
"prettier": "^1.18.2",
|
||||
"re-reselect": "^3.4.0",
|
||||
"react": "^16.7.0",
|
||||
"react-ace": "^8.0.0",
|
||||
"react-dnd": "^9.3.4",
|
||||
"react-dnd-html5-backend": "^9.3.4",
|
||||
"react-dnd-touch-backend": "^9.4.0",
|
||||
"react-dom": "^16.7.0",
|
||||
"react-json-view": "^1.19.1",
|
||||
"react-netlify-identity": "^0.1.9",
|
||||
"react-redux": "^6.0.0",
|
||||
"react-rnd": "^10.1.1",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1",
|
||||
"react-scripts": "^3.1.1",
|
||||
"react-select": "^3.0.8",
|
||||
"react-tabs": "^3.0.0",
|
||||
"redux": "^4.0.1",
|
||||
"redux-form": "^8.2.6",
|
||||
"redux-saga": "^1.0.0",
|
||||
"reselect": "^4.0.0",
|
||||
"styled-components": "^4.1.3",
|
||||
|
|
@ -79,6 +84,9 @@
|
|||
"not op_mini all"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/react-select": "^3.0.5",
|
||||
"@types/react-tabs": "^2.3.1",
|
||||
"@types/redux-form": "^8.1.9",
|
||||
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||
"@typescript-eslint/parser": "^2.0.0",
|
||||
"dotenv": "^8.1.0",
|
||||
|
|
|
|||
58
app/client/src/actions/actionActions.ts
Normal file
58
app/client/src/actions/actionActions.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { ReduxActionTypes } from "../constants/ReduxActionConstants";
|
||||
import { RestAction } from "../api/ActionAPI";
|
||||
|
||||
export const createAction = (payload: RestAction) => {
|
||||
return {
|
||||
type: ReduxActionTypes.CREATE_ACTION,
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchActions = () => {
|
||||
return {
|
||||
type: ReduxActionTypes.FETCH_ACTIONS_INIT,
|
||||
};
|
||||
};
|
||||
|
||||
export const selectAction = (payload: { id: string }) => {
|
||||
return {
|
||||
type: ReduxActionTypes.SELECT_ACTION,
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchApiConfig = (payload: { id: string }) => {
|
||||
return {
|
||||
type: ReduxActionTypes.FETCH_ACTION,
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
export const runAction = (payload: { id: string }) => {
|
||||
return {
|
||||
type: ReduxActionTypes.RUN_ACTION,
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteAction = (payload: { id: string }) => {
|
||||
return {
|
||||
type: ReduxActionTypes.DELETE_ACTION,
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
export const updateAction = (payload: { data: RestAction }) => {
|
||||
return {
|
||||
type: ReduxActionTypes.UPDATE_ACTION,
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
export default {
|
||||
createAction,
|
||||
fetchActions,
|
||||
fetchApiConfig,
|
||||
runAction,
|
||||
deleteAction,
|
||||
};
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import API, { HttpMethod } from "./Api";
|
||||
import { ApiResponse } from "./ApiResponses";
|
||||
import { ApiResponse, GenericApiResponse } from "./ApiResponses";
|
||||
import { APIRequest } from "../constants/ApiConstants";
|
||||
import { mapToPropList } from "../utils/AppsmithUtils";
|
||||
|
||||
export interface CreateActionRequest<T> extends APIRequest {
|
||||
resourceId: string;
|
||||
actionName: string;
|
||||
pageId: string;
|
||||
name: string;
|
||||
actionConfiguration: T;
|
||||
}
|
||||
|
||||
|
|
@ -15,9 +15,10 @@ export interface UpdateActionRequest<T> extends CreateActionRequest<T> {
|
|||
|
||||
export interface APIConfig {
|
||||
resourceId: string;
|
||||
actionName: string;
|
||||
pageId: string;
|
||||
name: string;
|
||||
requestHeaders: Record<string, string>;
|
||||
method: HttpMethod;
|
||||
httpMethod: HttpMethod;
|
||||
path: string;
|
||||
body: JSON;
|
||||
queryParams: Record<string, string>;
|
||||
|
|
@ -31,9 +32,9 @@ export interface Property {
|
|||
|
||||
export interface APIConfigRequest {
|
||||
headers: Property[];
|
||||
httpMethod: HttpMethod;
|
||||
httpMethod: string;
|
||||
path: string;
|
||||
body: JSON;
|
||||
body: JSON | string;
|
||||
queryParameters: Property[];
|
||||
}
|
||||
|
||||
|
|
@ -42,8 +43,17 @@ export interface QueryConfig {
|
|||
}
|
||||
|
||||
export interface ActionCreateUpdateResponse extends ApiResponse {
|
||||
actionId: string;
|
||||
dynamicBindingMap: Record<string, string>;
|
||||
id: string;
|
||||
jsonPathKeys: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface RestAction {
|
||||
id: string;
|
||||
name: string;
|
||||
resourceId: string;
|
||||
pluginId: string;
|
||||
pageId: string;
|
||||
actionConfiguration: APIConfigRequest;
|
||||
}
|
||||
|
||||
export interface ExecuteActionRequest extends APIRequest {
|
||||
|
|
@ -59,35 +69,26 @@ export interface ExecuteActionResponse extends ApiResponse {
|
|||
class ActionAPI extends API {
|
||||
static url = "v1/actions";
|
||||
|
||||
static createAPI(apiConfig: APIConfig): Promise<ActionCreateUpdateResponse> {
|
||||
const createAPI: CreateActionRequest<APIConfigRequest> = {
|
||||
resourceId: apiConfig.resourceId,
|
||||
actionName: apiConfig.actionName,
|
||||
actionConfiguration: {
|
||||
httpMethod: apiConfig.method,
|
||||
path: apiConfig.path,
|
||||
body: apiConfig.body,
|
||||
headers: mapToPropList(apiConfig.requestHeaders),
|
||||
queryParameters: mapToPropList(apiConfig.queryParams),
|
||||
},
|
||||
};
|
||||
return API.post(ActionAPI.url, createAPI);
|
||||
static fetchAPI(id: string): Promise<GenericApiResponse<RestAction>> {
|
||||
return API.get(`${ActionAPI.url}/${id}`);
|
||||
}
|
||||
|
||||
static updateAPI(apiConfig: APIConfig): Promise<ActionCreateUpdateResponse> {
|
||||
const updateAPI: UpdateActionRequest<APIConfigRequest> = {
|
||||
resourceId: apiConfig.resourceId,
|
||||
actionName: apiConfig.actionName,
|
||||
actionId: apiConfig.actionId,
|
||||
actionConfiguration: {
|
||||
httpMethod: apiConfig.method,
|
||||
path: apiConfig.path,
|
||||
body: apiConfig.body,
|
||||
headers: mapToPropList(apiConfig.requestHeaders),
|
||||
queryParameters: mapToPropList(apiConfig.queryParams),
|
||||
},
|
||||
};
|
||||
return API.post(ActionAPI.url, updateAPI);
|
||||
static createAPI(apiConfig: RestAction): Promise<ActionCreateUpdateResponse> {
|
||||
return API.post(ActionAPI.url, apiConfig);
|
||||
}
|
||||
|
||||
static fetchActions(): Promise<GenericApiResponse<RestAction[]>> {
|
||||
return API.get(ActionAPI.url);
|
||||
}
|
||||
|
||||
static updateAPI(
|
||||
apiConfig: Partial<RestAction>,
|
||||
): Promise<ActionCreateUpdateResponse> {
|
||||
return API.put(`${ActionAPI.url}/${apiConfig.id}`, null, apiConfig);
|
||||
}
|
||||
|
||||
static deleteAction(id: string) {
|
||||
return API.delete(`${ActionAPI.url}/${id}`);
|
||||
}
|
||||
|
||||
static createQuery(
|
||||
|
|
|
|||
|
|
@ -64,6 +64,12 @@ class Api {
|
|||
);
|
||||
}
|
||||
|
||||
static delete(url: string, queryParams?: any) {
|
||||
return axiosInstance.delete(
|
||||
url + this.convertObjectToQueryParams(queryParams),
|
||||
);
|
||||
}
|
||||
|
||||
static convertObjectToQueryParams(object: any): string {
|
||||
if (!_.isNil(object)) {
|
||||
const paramArray: string[] = _.map(_.keys(object), key => {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ export type ApiResponse = {
|
|||
data: any;
|
||||
};
|
||||
|
||||
export type GenericApiResponse<T> = {
|
||||
responseMeta: ResponseMeta;
|
||||
data: T;
|
||||
};
|
||||
|
||||
// NO_RESOURCE_FOUND, 1000, "Unable to find {0} with id {1}"
|
||||
// INVALID_PARAMTER, 4000, "Invalid parameter {0} provided in the input"
|
||||
// PLUGIN_NOT_INSTALLED, 4001, "Plugin {0} not installed"
|
||||
|
|
|
|||
9
app/client/src/assets/icons/form/trash.svg
Executable file
9
app/client/src/assets/icons/form/trash.svg
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.33341 13.3333C8.33341 13.7916 7.95841 14.1666 7.50008 14.1666C7.04175 14.1666 6.66675 13.7916 6.66675 13.3333V9.99996C6.66675 9.54163 7.04175 9.16663 7.50008 9.16663C7.95841 9.16663 8.33341 9.54163 8.33341 9.99996V13.3333ZM13.3334 13.3333C13.3334 13.7916 12.9584 14.1666 12.5001 14.1666C12.0417 14.1666 11.6667 13.7916 11.6667 13.3333V9.99996C11.6667 9.54163 12.0417 9.16663 12.5001 9.16663C12.9584 9.16663 13.3334 9.54163 13.3334 9.99996V13.3333ZM15.0001 15.8333C15.0001 16.2925 14.6267 16.6666 14.1667 16.6666H5.83341C5.37341 16.6666 5.00008 16.2925 5.00008 15.8333V6.66663H15.0001V15.8333ZM8.33341 3.60663C8.33341 3.47746 8.51175 3.33329 8.75008 3.33329H11.2501C11.4884 3.33329 11.6667 3.47746 11.6667 3.60663V4.99996H8.33341V3.60663ZM17.5001 4.99996H16.6667H13.3334V3.60663C13.3334 2.53663 12.3992 1.66663 11.2501 1.66663H8.75008C7.60091 1.66663 6.66675 2.53663 6.66675 3.60663V4.99996H3.33341H2.50008C2.04175 4.99996 1.66675 5.37496 1.66675 5.83329C1.66675 6.29163 2.04175 6.66663 2.50008 6.66663H3.33341V15.8333C3.33341 17.2116 4.45508 18.3333 5.83342 18.3333H14.1667C15.5451 18.3333 16.6667 17.2116 16.6667 15.8333V6.66663H17.5001C17.9584 6.66663 18.3334 6.29163 18.3334 5.83329C18.3334 5.37496 17.9584 4.99996 17.5001 4.99996Z" fill="#231F20"/>
|
||||
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="1" y="1" width="18" height="18">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.33341 13.3333C8.33341 13.7916 7.95841 14.1666 7.50008 14.1666C7.04175 14.1666 6.66675 13.7916 6.66675 13.3333V9.99996C6.66675 9.54163 7.04175 9.16663 7.50008 9.16663C7.95841 9.16663 8.33341 9.54163 8.33341 9.99996V13.3333ZM13.3334 13.3333C13.3334 13.7916 12.9584 14.1666 12.5001 14.1666C12.0417 14.1666 11.6667 13.7916 11.6667 13.3333V9.99996C11.6667 9.54163 12.0417 9.16663 12.5001 9.16663C12.9584 9.16663 13.3334 9.54163 13.3334 9.99996V13.3333ZM15.0001 15.8333C15.0001 16.2925 14.6267 16.6666 14.1667 16.6666H5.83341C5.37341 16.6666 5.00008 16.2925 5.00008 15.8333V6.66663H15.0001V15.8333ZM8.33341 3.60663C8.33341 3.47746 8.51175 3.33329 8.75008 3.33329H11.2501C11.4884 3.33329 11.6667 3.47746 11.6667 3.60663V4.99996H8.33341V3.60663ZM17.5001 4.99996H16.6667H13.3334V3.60663C13.3334 2.53663 12.3992 1.66663 11.2501 1.66663H8.75008C7.60091 1.66663 6.66675 2.53663 6.66675 3.60663V4.99996H3.33341H2.50008C2.04175 4.99996 1.66675 5.37496 1.66675 5.83329C1.66675 6.29163 2.04175 6.66663 2.50008 6.66663H3.33341V15.8333C3.33341 17.2116 4.45508 18.3333 5.83342 18.3333H14.1667C15.5451 18.3333 16.6667 17.2116 16.6667 15.8333V6.66663H17.5001C17.9584 6.66663 18.3334 6.29163 18.3334 5.83329C18.3334 5.37496 17.9584 4.99996 17.5001 4.99996Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0)">
|
||||
<rect width="20" height="20" fill="#A3B3BF"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
98
app/client/src/components/canvas/Button.tsx
Normal file
98
app/client/src/components/canvas/Button.tsx
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import React from "react";
|
||||
import { Button, IButtonProps, MaybeElement } from "@blueprintjs/core";
|
||||
import styled, { css } from "styled-components";
|
||||
import { Container } from "../../editorComponents/ContainerComponent";
|
||||
import { TextComponentProps } from "./TextViewComponent";
|
||||
|
||||
const ButtonColorStyles = css<ButtonStyleProps>`
|
||||
color: ${props => {
|
||||
if (props.filled) return props.theme.colors.textOnDarkBG;
|
||||
if (props.styleName) {
|
||||
if (props.styleName === "secondary")
|
||||
return props.theme.colors.OXFORD_BLUE;
|
||||
return props.theme.colors[props.styleName];
|
||||
}
|
||||
}};
|
||||
`;
|
||||
|
||||
const ButtonWrapper = styled(Button)<ButtonStyleProps>`
|
||||
&& {
|
||||
${ButtonColorStyles};
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: background-color 0.2s;
|
||||
background-color: ${props =>
|
||||
props.filled && props.styleName && props.theme.colors[props.styleName]};
|
||||
border: 1px solid
|
||||
${props =>
|
||||
props.styleName
|
||||
? props.theme.colors[props.styleName]
|
||||
: props.theme.colors.secondary};
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
outline: none;
|
||||
&&:hover,
|
||||
&&:focus {
|
||||
${ButtonColorStyles};
|
||||
background-color: ${props => {
|
||||
if (!props.filled) return props.theme.colors.secondaryDarker;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darker`];
|
||||
}
|
||||
}};
|
||||
border-color: ${props => {
|
||||
if (!props.filled) return;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darker`];
|
||||
}
|
||||
}};
|
||||
}
|
||||
&&:active {
|
||||
${ButtonColorStyles};
|
||||
background-color: ${props => {
|
||||
if (!props.filled) return props.theme.colors.secondaryDarkest;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darkest`];
|
||||
}
|
||||
}};
|
||||
border-color: ${props => {
|
||||
if (!props.filled) return;
|
||||
if (props.styleName !== "secondary") {
|
||||
return props.theme.colors[`${props.styleName}Darkest`];
|
||||
}
|
||||
}};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type ButtonStyleProps = {
|
||||
styleName?: "primary" | "secondary" | "error";
|
||||
filled?: boolean;
|
||||
};
|
||||
|
||||
// To be used in any other part of the app
|
||||
export const BaseButton = (props: IButtonProps & ButtonStyleProps) => {
|
||||
return <ButtonWrapper {...props} />;
|
||||
};
|
||||
|
||||
BaseButton.defaultProps = {
|
||||
styleName: "secondary",
|
||||
text: "Button Text",
|
||||
minimal: true,
|
||||
};
|
||||
|
||||
interface ButtonContainerProps extends TextComponentProps {
|
||||
icon?: MaybeElement;
|
||||
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
// To be used with the canvas
|
||||
const ButtonContainer = (props: ButtonContainerProps) => {
|
||||
return (
|
||||
<Container {...props}>
|
||||
<BaseButton icon={props.icon} text={props.text} onClick={props.onClick} />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default ButtonContainer;
|
||||
31
app/client/src/components/canvas/CreatableDropdown.tsx
Normal file
31
app/client/src/components/canvas/CreatableDropdown.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import React from "react";
|
||||
import Creatable from "react-select/creatable";
|
||||
|
||||
type DropdownProps = {
|
||||
options: Array<{
|
||||
value: string;
|
||||
label: string;
|
||||
}>;
|
||||
placeholder: string;
|
||||
};
|
||||
|
||||
const selectStyles = {
|
||||
container: (styles: any) => ({
|
||||
...styles,
|
||||
flex: 1,
|
||||
}),
|
||||
};
|
||||
|
||||
class CreatableDropdown extends React.Component<DropdownProps> {
|
||||
render() {
|
||||
return (
|
||||
<Creatable
|
||||
placeholder={this.props.placeholder}
|
||||
options={this.props.options}
|
||||
styles={selectStyles}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CreatableDropdown;
|
||||
38
app/client/src/components/canvas/Dropdown.tsx
Normal file
38
app/client/src/components/canvas/Dropdown.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import React from "react";
|
||||
import Select from "react-select";
|
||||
import { WrappedFieldInputProps } from "redux-form";
|
||||
|
||||
type DropdownProps = {
|
||||
options: Array<{
|
||||
value: string;
|
||||
label: string;
|
||||
}>;
|
||||
input: WrappedFieldInputProps;
|
||||
};
|
||||
|
||||
const selectStyles = {
|
||||
control: (styles: any) => ({
|
||||
...styles,
|
||||
width: 100,
|
||||
}),
|
||||
};
|
||||
|
||||
export const BaseDropdown = (props: DropdownProps) => {
|
||||
const { input, options } = props;
|
||||
return (
|
||||
<Select
|
||||
defaultValue={options[0]}
|
||||
options={options}
|
||||
styles={selectStyles}
|
||||
{...input}
|
||||
onChange={value => input.onChange(value)}
|
||||
onBlur={() => input.onBlur(input.value)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Dropdown = (props: DropdownProps) => {
|
||||
return <BaseDropdown {...props} />;
|
||||
};
|
||||
|
||||
export default Dropdown;
|
||||
41
app/client/src/components/canvas/TabbedView.tsx
Normal file
41
app/client/src/components/canvas/TabbedView.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import React from "react";
|
||||
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
|
||||
import "react-tabs/style/react-tabs.scss";
|
||||
import styled from "styled-components";
|
||||
|
||||
const TabsWrapper = styled(Tabs)`
|
||||
ul {
|
||||
border-bottom-color: #d0d7dd;
|
||||
li {
|
||||
&.react-tabs__tab--selected {
|
||||
border-color: #d0d7dd;
|
||||
left: -1px;
|
||||
border-radius: 0;
|
||||
border-top: 5px solid ${props => props.theme.colors.primary};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type TabbedViewComponentType = {
|
||||
tabs: Array<{
|
||||
key: string;
|
||||
title: string;
|
||||
panelComponent: () => React.ReactNode;
|
||||
}>;
|
||||
};
|
||||
|
||||
export const BaseTabbedView = (props: TabbedViewComponentType) => {
|
||||
return (
|
||||
<TabsWrapper>
|
||||
<TabList>
|
||||
{props.tabs.map(tab => (
|
||||
<Tab key={tab.key}>{tab.title}</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
{props.tabs.map(tab => (
|
||||
<TabPanel key={tab.key}>{tab.panelComponent()}</TabPanel>
|
||||
))}
|
||||
</TabsWrapper>
|
||||
);
|
||||
};
|
||||
53
app/client/src/components/canvas/TextInputComponent.tsx
Normal file
53
app/client/src/components/canvas/TextInputComponent.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import React from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { WrappedFieldInputProps, WrappedFieldMetaProps } from "redux-form";
|
||||
import { ComponentProps } from "../../editorComponents/BaseComponent";
|
||||
import { Container } from "../../editorComponents/ContainerComponent";
|
||||
|
||||
const InputStyles = css`
|
||||
padding: 5px;
|
||||
flex: 1;
|
||||
border: 1px solid ${props => props.theme.colors.inputInactiveBorders};
|
||||
border-radius: 4px;
|
||||
height: 32px;
|
||||
background-color: ${props => props.theme.colors.inputInactiveBG};
|
||||
&:focus {
|
||||
border-color: ${props => props.theme.colors.secondary};
|
||||
background-color: ${props => props.theme.colors.textOnDarkBG};
|
||||
outline: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const Input = styled.input`
|
||||
${InputStyles}
|
||||
`;
|
||||
|
||||
const TextArea = styled.textarea`
|
||||
${InputStyles}
|
||||
height: 100px;
|
||||
`;
|
||||
|
||||
export interface TextInputProps {
|
||||
placeholderMessage?: string;
|
||||
multiline?: boolean;
|
||||
input?: WrappedFieldInputProps;
|
||||
meta?: WrappedFieldMetaProps;
|
||||
}
|
||||
|
||||
export const BaseTextInput = (props: TextInputProps) => {
|
||||
const { placeholderMessage, multiline, input } = props;
|
||||
if (multiline) {
|
||||
return <TextArea placeholder={placeholderMessage} {...input} />;
|
||||
}
|
||||
return <Input placeholder={placeholderMessage} {...input} />;
|
||||
};
|
||||
|
||||
const TextInputComponent = (props: TextInputProps & ComponentProps) => {
|
||||
return (
|
||||
<Container {...props}>
|
||||
<BaseTextInput {...props} />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextInputComponent;
|
||||
|
|
@ -1,7 +1,23 @@
|
|||
import * as React from "react";
|
||||
import { ComponentProps } from "./BaseComponent";
|
||||
import { Text } from "@blueprintjs/core";
|
||||
import { Container } from "./ContainerComponent";
|
||||
import styled from "styled-components";
|
||||
import { ComponentProps } from "../../editorComponents/BaseComponent";
|
||||
import { Container } from "../../editorComponents/ContainerComponent";
|
||||
|
||||
type TextStyleProps = {
|
||||
styleName: "primary" | "secondary" | "error";
|
||||
};
|
||||
|
||||
export const BaseText = styled(Text)<TextStyleProps>`
|
||||
color: ${props => props.theme.colors[props.styleName]};
|
||||
`;
|
||||
|
||||
export interface TextComponentProps extends ComponentProps {
|
||||
text?: string;
|
||||
ellipsize?: boolean;
|
||||
tagName?: keyof JSX.IntrinsicElements;
|
||||
}
|
||||
|
||||
class TextComponent extends React.Component<TextComponentProps> {
|
||||
render() {
|
||||
return (
|
||||
|
|
@ -14,10 +30,4 @@ class TextComponent extends React.Component<TextComponentProps> {
|
|||
}
|
||||
}
|
||||
|
||||
export interface TextComponentProps extends ComponentProps {
|
||||
text?: string;
|
||||
ellipsize?: boolean;
|
||||
tagName?: keyof JSX.IntrinsicElements;
|
||||
}
|
||||
|
||||
export default TextComponent;
|
||||
7
app/client/src/components/editor/FormContainer.tsx
Normal file
7
app/client/src/components/editor/FormContainer.tsx
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { Form } from "redux-form";
|
||||
import styled from "styled-components";
|
||||
|
||||
export default styled(Form)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
10
app/client/src/components/editor/FormLabel.tsx
Normal file
10
app/client/src/components/editor/FormLabel.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import styled from "styled-components";
|
||||
|
||||
export default styled.p`
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0.02em;
|
||||
color: #4e5d78;
|
||||
margin-bottom: 5px;
|
||||
`;
|
||||
9
app/client/src/components/editor/FormRow.tsx
Normal file
9
app/client/src/components/editor/FormRow.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import styled from "styled-components";
|
||||
|
||||
export default styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
37
app/client/src/components/editor/JSONEditor.tsx
Normal file
37
app/client/src/components/editor/JSONEditor.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import React from "react";
|
||||
import AceEditor from "react-ace";
|
||||
import "ace-builds/src-noconflict/mode-json";
|
||||
import "ace-builds/src-noconflict/theme-textmate";
|
||||
|
||||
const aceOnBlur = (onBlur: any) => (_event: any, editor?: any) => {
|
||||
const value = editor.getValue();
|
||||
onBlur(value);
|
||||
};
|
||||
const JSONEditor = (props: any) => {
|
||||
const { input } = props;
|
||||
return (
|
||||
<AceEditor
|
||||
mode="json"
|
||||
theme="textmate"
|
||||
fontSize={14}
|
||||
showPrintMargin={true}
|
||||
showGutter={true}
|
||||
highlightActiveLine={true}
|
||||
width="100%"
|
||||
setOptions={{
|
||||
enableBasicAutocompletion: true,
|
||||
enableLiveAutocompletion: false,
|
||||
enableSnippets: false,
|
||||
showLineNumbers: true,
|
||||
tabSize: 2,
|
||||
}}
|
||||
name={input.name}
|
||||
onBlur={aceOnBlur(input.onBlur)}
|
||||
onChange={input.onChange}
|
||||
onFocus={input.onFocus}
|
||||
value={input.value}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default JSONEditor;
|
||||
28
app/client/src/components/editor/JSONViewer.tsx
Normal file
28
app/client/src/components/editor/JSONViewer.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import React from "react";
|
||||
import ReactJson from "react-json-view";
|
||||
import styled from "styled-components";
|
||||
|
||||
const JSONViewWrapper = styled.div`
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
`;
|
||||
|
||||
const JSONViewer = (props: { data: JSON }) => {
|
||||
if (!props.data) return null;
|
||||
return (
|
||||
<JSONViewWrapper>
|
||||
<ReactJson
|
||||
src={props.data}
|
||||
displayObjectSize={false}
|
||||
displayDataTypes={false}
|
||||
indentWidth={2}
|
||||
enableClipboard={false}
|
||||
style={{
|
||||
fontSize: "10px",
|
||||
}}
|
||||
/>
|
||||
</JSONViewWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default JSONViewer;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import NavBarItem from "./NavBarItem";
|
||||
import { MenuIcons } from "../icons/MenuIcons";
|
||||
import { BUILDER_URL, API_EDITOR_URL } from "../constants/routes";
|
||||
import { MenuIcons } from "../../icons/MenuIcons";
|
||||
import { BUILDER_URL, API_EDITOR_URL } from "../../constants/routes";
|
||||
import Sidebar from "./Sidebar";
|
||||
|
||||
const Container = styled.div`
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
import React from "react";
|
||||
import { Switch, Route } from "react-router";
|
||||
import styled from "styled-components";
|
||||
import { API_EDITOR_URL, BUILDER_URL } from "../constants/routes";
|
||||
import WidgetSidebar from "../pages/Editor/WidgetSidebar";
|
||||
import ApiSidebar from "../pages/Editor/ApiSidebar";
|
||||
import {
|
||||
API_EDITOR_URL,
|
||||
BUILDER_URL,
|
||||
API_EDITOR_ID_URL,
|
||||
} from "../../constants/routes";
|
||||
import WidgetSidebar from "../../pages/Editor/WidgetSidebar";
|
||||
import ApiSidebar from "../../pages/Editor/ApiSidebar";
|
||||
|
||||
const SidebarWrapper = styled.div`
|
||||
flex: 7;
|
||||
|
|
@ -20,6 +24,7 @@ class Sidebar extends React.Component {
|
|||
<Switch>
|
||||
<Route exact path={BUILDER_URL} component={WidgetSidebar} />
|
||||
<Route exact path={API_EDITOR_URL} component={ApiSidebar} />
|
||||
<Route exact path={API_EDITOR_ID_URL()} component={ApiSidebar} />
|
||||
</Switch>
|
||||
</SidebarWrapper>
|
||||
</React.Fragment>
|
||||
26
app/client/src/components/fields/DropdownField.tsx
Normal file
26
app/client/src/components/fields/DropdownField.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import React from "react";
|
||||
import _ from "lodash";
|
||||
import { BaseDropdown } from "../canvas/Dropdown";
|
||||
import { Field } from "redux-form";
|
||||
|
||||
interface DropdownFieldProps {
|
||||
name: string;
|
||||
options: Array<{
|
||||
label: string;
|
||||
value: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
const DropdownField = (props: DropdownFieldProps) => {
|
||||
return (
|
||||
<Field
|
||||
name={props.name}
|
||||
component={BaseDropdown}
|
||||
options={props.options}
|
||||
format={(value: string) => _.find(props.options, { value })}
|
||||
normalize={(option: { value: string }) => option.value}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default DropdownField;
|
||||
17
app/client/src/components/fields/JSONEditorField.tsx
Normal file
17
app/client/src/components/fields/JSONEditorField.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from "react";
|
||||
import { Field } from "redux-form";
|
||||
import JSONEditor from "../editor/JSONEditor";
|
||||
|
||||
const JSONEditorField = (props: { name: string }) => {
|
||||
return (
|
||||
<Field
|
||||
name={props.name}
|
||||
component={JSONEditor}
|
||||
format={(value: string | object) =>
|
||||
typeof value === "string" ? value : JSON.stringify(value)
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default JSONEditorField;
|
||||
73
app/client/src/components/fields/KeyValueFieldArray.tsx
Normal file
73
app/client/src/components/fields/KeyValueFieldArray.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import React from "react";
|
||||
import { FieldArray, WrappedFieldArrayProps } from "redux-form";
|
||||
import { Icon } from "@blueprintjs/core";
|
||||
import { FormIcons } from "../../icons/FormIcons";
|
||||
import TextField from "./TextField";
|
||||
import FormRow from "../editor/FormRow";
|
||||
import FormLabel from "../editor/FormLabel";
|
||||
import styled from "styled-components";
|
||||
|
||||
const FormRowWithLabel = styled(FormRow)`
|
||||
flex-wrap: wrap;
|
||||
${FormLabel} {
|
||||
width: 100%;
|
||||
}
|
||||
& svg {
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
|
||||
const KeyValueRow = (props: Props & WrappedFieldArrayProps) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{props.fields.length === 0 && (
|
||||
<FormRowWithLabel>
|
||||
<FormLabel>{props.label}</FormLabel>
|
||||
<TextField name={`${props.name}[0].key`} placeholderMessage="Key" />
|
||||
<TextField
|
||||
name={`${props.name}[0].value`}
|
||||
placeholderMessage="Value"
|
||||
/>
|
||||
<Icon
|
||||
icon="plus"
|
||||
iconSize={20}
|
||||
onClick={() => props.fields.push({ key: "", value: "" })}
|
||||
color={"#A3B3BF"}
|
||||
/>
|
||||
</FormRowWithLabel>
|
||||
)}
|
||||
{props.fields.map((field: any, index: number) => (
|
||||
<FormRowWithLabel key={index}>
|
||||
{index === 0 && <FormLabel>{props.label}</FormLabel>}
|
||||
<TextField name={`${field}.key`} placeholderMessage="Key" />
|
||||
<TextField name={`${field}.value`} placeholderMessage="Value" />
|
||||
{index === props.fields.length - 1 ? (
|
||||
<Icon
|
||||
icon="plus"
|
||||
iconSize={20}
|
||||
onClick={() => props.fields.push({ key: "", value: "" })}
|
||||
color={"#A3B3BF"}
|
||||
/>
|
||||
) : (
|
||||
<FormIcons.DELETE_ICON
|
||||
height={20}
|
||||
width={20}
|
||||
onClick={() => props.fields.remove(index)}
|
||||
/>
|
||||
)}
|
||||
</FormRowWithLabel>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
type Props = {
|
||||
name: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
const KeyValueFieldArray = (props: Props) => {
|
||||
return <FieldArray name={props.name} component={KeyValueRow} {...props} />;
|
||||
};
|
||||
|
||||
export default KeyValueFieldArray;
|
||||
16
app/client/src/components/fields/TextField.tsx
Normal file
16
app/client/src/components/fields/TextField.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import React from "react";
|
||||
import { Field } from "redux-form";
|
||||
import { BaseTextInput, TextInputProps } from "../canvas/TextInputComponent";
|
||||
|
||||
interface TextFieldProps {
|
||||
name: string;
|
||||
}
|
||||
|
||||
class TextField extends React.Component<TextFieldProps & TextInputProps> {
|
||||
render() {
|
||||
const { name } = this.props;
|
||||
return <Field name={name} component={BaseTextInput} {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default TextField;
|
||||
179
app/client/src/components/forms/ApiEditorForm.tsx
Normal file
179
app/client/src/components/forms/ApiEditorForm.tsx
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
import React from "react";
|
||||
import { reduxForm, InjectedFormProps, FormSubmitHandler } from "redux-form";
|
||||
import FormRow from "../editor/FormRow";
|
||||
import TextField from "../fields/TextField";
|
||||
import {
|
||||
FORM_INITIAL_VALUES,
|
||||
HTTP_METHOD_OPTIONS,
|
||||
} from "../../constants/ApiEditorConstants";
|
||||
import CreatableDropdown from "../canvas/CreatableDropdown";
|
||||
import FormLabel from "../editor/FormLabel";
|
||||
import { BaseText } from "../canvas/TextViewComponent";
|
||||
import { BaseTabbedView } from "../canvas/TabbedView";
|
||||
import styled from "styled-components";
|
||||
import FormContainer from "../editor/FormContainer";
|
||||
import { BaseButton } from "../canvas/Button";
|
||||
import KeyValueFieldArray from "../fields/KeyValueFieldArray";
|
||||
import JSONEditorField from "../fields/JSONEditorField";
|
||||
import DropdownField from "../fields/DropdownField";
|
||||
import { RestAction } from "../../api/ActionAPI";
|
||||
import JSONViewer from "../../components/editor/JSONViewer";
|
||||
|
||||
const Form = styled(FormContainer)`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
${FormRow} {
|
||||
flex-wrap: wrap;
|
||||
padding: ${props => props.theme.spaces[3]}px;
|
||||
& > * {
|
||||
margin-right: 5px;
|
||||
}
|
||||
${FormLabel} {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const SecondaryWrapper = styled.div`
|
||||
display: flex;
|
||||
border-top: 1px solid #d0d7dd;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const ForwardSlash = styled.div`
|
||||
&& {
|
||||
margin: 0 10px;
|
||||
height: 22px;
|
||||
width: 1px;
|
||||
background-color: #d0d7dd;
|
||||
transform: rotate(27deg);
|
||||
}
|
||||
`;
|
||||
|
||||
const RequestParamsWrapper = styled.div`
|
||||
flex: 5;
|
||||
border-right: 1px solid #d0d7dd;
|
||||
`;
|
||||
|
||||
const ResponseWrapper = styled.div`
|
||||
flex: 4;
|
||||
`;
|
||||
|
||||
const ActionButton = styled(BaseButton)`
|
||||
max-width: 72px;
|
||||
margin: 0 5px;
|
||||
`;
|
||||
|
||||
const ResponseMetaInfo = styled.div`
|
||||
display: flex;
|
||||
${BaseText} {
|
||||
color: #768896;
|
||||
margin: 0 5px;
|
||||
}
|
||||
`;
|
||||
|
||||
const JSONEditorFieldWrapper = styled.div`
|
||||
flex: 1;
|
||||
border: 1px solid #d0d7dd;
|
||||
border-radius: 4px;
|
||||
`;
|
||||
|
||||
interface APIFormProps {
|
||||
onSubmit: FormSubmitHandler<RestAction>;
|
||||
onSaveClick: () => void;
|
||||
onRunClick: () => void;
|
||||
onDeleteClick: () => void;
|
||||
response: any;
|
||||
}
|
||||
|
||||
type Props = APIFormProps & InjectedFormProps<RestAction, APIFormProps>;
|
||||
|
||||
class ApiEditorForm extends React.Component<Props> {
|
||||
render() {
|
||||
const { onSaveClick, onDeleteClick, onRunClick } = this.props;
|
||||
return (
|
||||
<Form>
|
||||
<FormRow>
|
||||
<TextField name="name" placeholderMessage="API Name" />
|
||||
<ActionButton
|
||||
text="Delete"
|
||||
styleName="error"
|
||||
onClick={onDeleteClick}
|
||||
/>
|
||||
<ActionButton text="Run" styleName="secondary" onClick={onRunClick} />
|
||||
<ActionButton
|
||||
text="Save"
|
||||
styleName="primary"
|
||||
filled
|
||||
onClick={onSaveClick}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<DropdownField
|
||||
name="actionConfiguration.httpMethod"
|
||||
options={HTTP_METHOD_OPTIONS}
|
||||
/>
|
||||
<CreatableDropdown options={[]} placeholder="Resource" />
|
||||
<ForwardSlash />
|
||||
<TextField
|
||||
placeholderMessage="API Path"
|
||||
name="actionConfiguration.path"
|
||||
/>
|
||||
</FormRow>
|
||||
<SecondaryWrapper>
|
||||
<RequestParamsWrapper>
|
||||
<KeyValueFieldArray
|
||||
name="actionConfiguration.headers"
|
||||
label="Headers"
|
||||
/>
|
||||
<KeyValueFieldArray
|
||||
name="actionConfiguration.queryParameters"
|
||||
label="Params"
|
||||
/>
|
||||
<FormRow>
|
||||
<FormLabel>Post Body</FormLabel>
|
||||
<JSONEditorFieldWrapper>
|
||||
<JSONEditorField name="actionConfiguration.body" />
|
||||
</JSONEditorFieldWrapper>
|
||||
</FormRow>
|
||||
</RequestParamsWrapper>
|
||||
<ResponseWrapper>
|
||||
<FormRow>
|
||||
<BaseText styleName="secondary">
|
||||
{this.props.response.statusCode}
|
||||
</BaseText>
|
||||
<ResponseMetaInfo>
|
||||
<BaseText styleName="secondary">300ms</BaseText>
|
||||
<BaseText styleName="secondary">203 kb</BaseText>
|
||||
</ResponseMetaInfo>
|
||||
</FormRow>
|
||||
<BaseTabbedView
|
||||
tabs={[
|
||||
{
|
||||
key: "body",
|
||||
title: "Response Body",
|
||||
panelComponent: () => (
|
||||
<JSONViewer data={this.props.response.body} />
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "headers",
|
||||
title: "Response Headers",
|
||||
panelComponent: () => (
|
||||
<JSONViewer data={this.props.response.headers} />
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</ResponseWrapper>
|
||||
</SecondaryWrapper>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default reduxForm<RestAction, APIFormProps>({
|
||||
form: "ApiEditorForm",
|
||||
enableReinitialize: true,
|
||||
initialValues: FORM_INITIAL_VALUES,
|
||||
})(ApiEditorForm);
|
||||
|
|
@ -61,8 +61,8 @@ export interface DownloadDataActionPayload extends ActionPayload {
|
|||
}
|
||||
|
||||
export interface PageAction {
|
||||
actionId: string;
|
||||
id: string;
|
||||
actionType: ActionType;
|
||||
actionName: string;
|
||||
dynamicBindings?: string[];
|
||||
name: string;
|
||||
jsonPathKeys?: string[];
|
||||
}
|
||||
|
|
|
|||
10
app/client/src/constants/ApiEditorConstants.ts
Normal file
10
app/client/src/constants/ApiEditorConstants.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE"];
|
||||
|
||||
export const HTTP_METHOD_OPTIONS = HTTP_METHODS.map(method => ({
|
||||
label: method,
|
||||
value: method,
|
||||
}));
|
||||
|
||||
export const FORM_INITIAL_VALUES = {
|
||||
resourceId: "5d808014795dc6000482bc83",
|
||||
};
|
||||
|
|
@ -3,7 +3,11 @@ export const Colors: Record<string, string> = {
|
|||
WHITE: "#FFFFFF",
|
||||
POLAR: "#E9FAF3",
|
||||
GEYSER: "#D3DEE3",
|
||||
GEYSER_LIGHT: "#D0D7DD",
|
||||
ATHENS_GRAY: "#FAFBFC",
|
||||
CONCRETE: "#F3F3F3",
|
||||
MYSTIC: "#E1E8ED",
|
||||
AQUA_HAZE: "#EEF2F5",
|
||||
|
||||
BLACK: "#000000",
|
||||
BLACK_PEARL: "#040627",
|
||||
|
|
@ -14,8 +18,11 @@ export const Colors: Record<string, string> = {
|
|||
PORCELAIN: "#EBEEF0",
|
||||
HIT_GRAY: "#A1ACB3",
|
||||
JUNGLE_MIST: "#BCCCD9",
|
||||
MERCURY: "#E8E8E8",
|
||||
|
||||
GREEN: "#29CCA3",
|
||||
JUNGLE_GREEN: "#24BA91",
|
||||
JUNGLE_GREEN_DARKER: "#30A481",
|
||||
RED: "#CE4257",
|
||||
PURPLE: "#6871EF",
|
||||
OXFORD_BLUE: "#2E3D49",
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type PropertyPaneTheme = {
|
|||
export type Theme = {
|
||||
radii: Array<number>;
|
||||
fontSizes: Array<number>;
|
||||
drawerWidth: string;
|
||||
spaces: Array<number>;
|
||||
fontWeights: Array<number>;
|
||||
colors: Record<string, Color>;
|
||||
|
|
@ -62,10 +63,19 @@ export const theme: Theme = {
|
|||
width: 250,
|
||||
height: 600,
|
||||
},
|
||||
drawerWidth: "80%",
|
||||
colors: {
|
||||
primary: Colors.GREEN,
|
||||
primaryDarker: Colors.JUNGLE_GREEN,
|
||||
primaryDarkest: Colors.JUNGLE_GREEN_DARKER,
|
||||
secondary: Colors.GEYSER_LIGHT,
|
||||
secondaryDarker: Colors.CONCRETE,
|
||||
secondaryDarkest: Colors.MERCURY,
|
||||
error: Colors.RED,
|
||||
info: Colors.SLATE_GRAY,
|
||||
hover: Colors.POLAR,
|
||||
inputInactiveBorders: Colors.MYSTIC,
|
||||
inputInactiveBG: Colors.AQUA_HAZE,
|
||||
textDefault: Colors.BLACK_PEARL,
|
||||
textOnDarkBG: Colors.WHITE,
|
||||
textAnchor: Colors.PURPLE,
|
||||
|
|
@ -92,7 +102,7 @@ export const theme: Theme = {
|
|||
color: Colors.FRENCH_PASS,
|
||||
},
|
||||
],
|
||||
sidebarWidth: "350px",
|
||||
sidebarWidth: "300px",
|
||||
headerHeight: "50px",
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import styled from "styled-components";
|
||||
import { Color } from "../constants/Colors";
|
||||
import { Color } from "./Colors";
|
||||
|
||||
export type IconProps = {
|
||||
width: number;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ export const ReduxActionTypes: { [key: string]: string } = {
|
|||
FETCH_PROPERTY_PANE_CONFIGS_SUCCESS: "FETCH_PROPERTY_PANE_CONFIGS_SUCCESS",
|
||||
FETCH_CONFIGS_INIT: "FETCH_CONFIGS_INIT",
|
||||
ADD_WIDGET_REF: "ADD_WIDGET_REF",
|
||||
CREATE_ACTION: "CREATE_ACTION",
|
||||
FETCH_ACTIONS_INIT: "FETCH_ACTIONS_INIT",
|
||||
FETCH_ACTIONS_SUCCESS: "FETCH_ACTIONS_SUCCESS",
|
||||
FETCH_ACTION: "FETCH_ACTION",
|
||||
RUN_ACTION: "RUN_ACTION",
|
||||
RUN_ACTION_SUCCESS: "RUN_ACTION_SUCCESS",
|
||||
UPDATE_ACTION: "UPDATE_ACTION",
|
||||
DELETE_ACTION: "DELETE_ACTION",
|
||||
};
|
||||
export type ReduxActionType = (typeof ReduxActionTypes)[keyof typeof ReduxActionTypes];
|
||||
|
||||
|
|
@ -57,6 +65,7 @@ export const ReduxActionErrorTypes: { [key: string]: string } = {
|
|||
FETCH_PROPERTY_PANE_CONFIGS_ERROR: "FETCH_PROPERTY_PANE_CONFIGS_ERROR",
|
||||
FETCH_CONFIGS_ERROR: "FETCH_CONFIGS_ERROR",
|
||||
PROPERTY_PANE_ERROR: "PROPERTY_PANE_ERROR",
|
||||
FETCH_ACTIONS_ERROR: "FETCH_ACTIONS_ERROR",
|
||||
};
|
||||
export type ReduxActionErrorType = (typeof ReduxActionErrorTypes)[keyof typeof ReduxActionErrorTypes];
|
||||
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ export const BASE_URL = "/";
|
|||
export const LOGIN_URL = "/login";
|
||||
export const BUILDER_URL = "/builder";
|
||||
export const API_EDITOR_URL = `${BUILDER_URL}/api`;
|
||||
export const API_EDITOR_ID_URL = (id = ":id") => `${API_EDITOR_URL}/${id}`;
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import React from "react";
|
||||
import { Button, MaybeElement } from "@blueprintjs/core";
|
||||
import { TextComponentProps } from "./TextComponent";
|
||||
import { Container } from "./ContainerComponent";
|
||||
|
||||
class ButtonComponent extends React.Component<ButtonComponentProps> {
|
||||
render() {
|
||||
return (
|
||||
<Container {...this.props}>
|
||||
<Button icon={this.props.icon} onClick={this.props.onClick}>
|
||||
{this.props.text}
|
||||
</Button>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface ButtonComponentProps extends TextComponentProps {
|
||||
icon?: MaybeElement;
|
||||
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
export default ButtonComponent;
|
||||
|
|
@ -17,13 +17,11 @@ export const Container = styled("div")<ContainerProps>`
|
|||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
padding: ${props => props.theme.spaces[8]}px ${props =>
|
||||
props.theme.spaces[1]}px ${props => props.theme.spaces[1]}px;
|
||||
padding: ${props => props.theme.spaces[1]}px;
|
||||
&:after {
|
||||
content: "${props => props.widgetName}";
|
||||
position: absolute;
|
||||
left: ${props => props.theme.spaces[1]}px;
|
||||
top: ${props => props.theme.spaces[1]}px;
|
||||
top: -${props => props.theme.spaces[8]}px;
|
||||
font-size: ${props => props.theme.fontSizes[2]}px;
|
||||
color: ${props => props.theme.colors.containerBorder};
|
||||
text-align: left;
|
||||
|
|
|
|||
22
app/client/src/icons/FormIcons.tsx
Normal file
22
app/client/src/icons/FormIcons.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import React from "react";
|
||||
import { Icon } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { IconProps, IconWrapper } from "../constants/IconConstants";
|
||||
import { ReactComponent as DeleteIcon } from "../assets/icons/form/trash.svg";
|
||||
|
||||
/* eslint-disable react/display-name */
|
||||
|
||||
export const FormIcons: {
|
||||
[id: string]: Function;
|
||||
} = {
|
||||
DELETE_ICON: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<DeleteIcon />
|
||||
</IconWrapper>
|
||||
),
|
||||
PLUS_ICON: (props: IconProps) => (
|
||||
<IconWrapper {...props}>
|
||||
<Icon icon={IconNames.PLUS} color={props.color} iconSize={props.height} />
|
||||
</IconWrapper>
|
||||
),
|
||||
};
|
||||
|
|
@ -42,10 +42,10 @@ const PageMockResponse: FetchPageResponse = {
|
|||
},
|
||||
actions: [
|
||||
{
|
||||
actionId: "5d8082e2795dc6000482bc84",
|
||||
id: "5d8082e2795dc6000482bc84",
|
||||
actionType: "API" as ActionType,
|
||||
actionName: "getUsers",
|
||||
dynamicBindings: ["$.apiData.0.name"],
|
||||
name: "getUsers",
|
||||
jsonPathKeys: ["$.apiData.0.name"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,120 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { submit, initialize, getFormValues } from "redux-form";
|
||||
import ApiEditorForm from "../../components/forms/ApiEditorForm";
|
||||
import {
|
||||
createAction,
|
||||
runAction,
|
||||
deleteAction,
|
||||
updateAction,
|
||||
} from "../../actions/actionActions";
|
||||
import { RestAction } from "../../api/ActionAPI";
|
||||
import { AppState } from "../../reducers";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { API_EDITOR_URL } from "../../constants/routes";
|
||||
|
||||
interface ReduxStateProps {
|
||||
actions: RestAction[];
|
||||
response: any;
|
||||
formData: any;
|
||||
}
|
||||
interface ReduxActionProps {
|
||||
submitForm: (name: string) => void;
|
||||
createAction: (values: RestAction) => void;
|
||||
runAction: (id: string) => void;
|
||||
deleteAction: (id: string) => void;
|
||||
updateAction: (data: RestAction) => void;
|
||||
initialize: (formName: string, data?: Partial<RestAction>) => void;
|
||||
}
|
||||
|
||||
type Props = ReduxActionProps &
|
||||
ReduxStateProps &
|
||||
RouteComponentProps<{ id: string }>;
|
||||
|
||||
class ApiEditor extends React.Component<Props> {
|
||||
componentDidMount(): void {
|
||||
const currentId = this.props.match.params.id;
|
||||
if (!currentId) return;
|
||||
if (!this.props.actions.length) {
|
||||
this.props.history.push(API_EDITOR_URL);
|
||||
return;
|
||||
}
|
||||
const data = this.props.actions.filter(
|
||||
action => action.id === currentId,
|
||||
)[0];
|
||||
this.props.initialize("ApiEditorForm", data);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Readonly<Props>): void {
|
||||
const currentId = this.props.match.params.id;
|
||||
if (currentId && currentId !== prevProps.match.params.id) {
|
||||
const data = this.props.actions.filter(
|
||||
action => action.id === currentId,
|
||||
)[0];
|
||||
this.props.initialize("ApiEditorForm", data);
|
||||
}
|
||||
}
|
||||
|
||||
handleSubmit = (values: RestAction) => {
|
||||
const { formData } = this.props;
|
||||
const data: RestAction = {
|
||||
...formData,
|
||||
actionConfiguration: {
|
||||
...formData.actionConfiguration,
|
||||
body: formData.actionConfiguration.body
|
||||
? typeof formData.actionConfiguration.body === "string"
|
||||
? JSON.parse(formData.actionConfiguration.body)
|
||||
: formData.actionConfiguration.body
|
||||
: null,
|
||||
},
|
||||
};
|
||||
if (data.id) {
|
||||
this.props.updateAction(data);
|
||||
} else {
|
||||
this.props.createAction(data);
|
||||
}
|
||||
};
|
||||
|
||||
handleSaveClick = () => {
|
||||
this.props.submitForm("ApiEditorForm");
|
||||
};
|
||||
handleDeleteClick = () => {
|
||||
this.props.deleteAction(this.props.match.params.id);
|
||||
};
|
||||
handleRunClick = () => {
|
||||
this.props.runAction(this.props.match.params.id);
|
||||
};
|
||||
|
||||
class ApiEditor extends React.Component {
|
||||
render() {
|
||||
return <span>API editor</span>;
|
||||
return (
|
||||
<ApiEditorForm
|
||||
onSubmit={this.handleSubmit}
|
||||
onSaveClick={this.handleSaveClick}
|
||||
onDeleteClick={this.handleDeleteClick}
|
||||
onRunClick={this.handleRunClick}
|
||||
response={this.props.response}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ApiEditor;
|
||||
const mapStateToProps = (state: AppState): ReduxStateProps => ({
|
||||
actions: state.entities.actions.data,
|
||||
response: state.entities.actions.response,
|
||||
formData: getFormValues("ApiEditorForm")(state),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: any): ReduxActionProps => ({
|
||||
submitForm: (name: string) => dispatch(submit(name)),
|
||||
createAction: (action: RestAction) => dispatch(createAction(action)),
|
||||
runAction: (id: string) => dispatch(runAction({ id })),
|
||||
deleteAction: (id: string) => dispatch(deleteAction({ id })),
|
||||
updateAction: (data: RestAction) => dispatch(updateAction({ data })),
|
||||
initialize: (formName: string, data?: Partial<RestAction>) =>
|
||||
dispatch(initialize(formName, data)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(ApiEditor);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,98 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import styled from "styled-components";
|
||||
import { AppState } from "../../reducers";
|
||||
import { fetchActions } from "../../actions/actionActions";
|
||||
import { ActionDataState } from "../../reducers/entityReducers/actionsReducer";
|
||||
import { API_EDITOR_ID_URL } from "../../constants/routes";
|
||||
|
||||
const ApiItem = styled.div<{ isSelected: boolean }>`
|
||||
width: 100%;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
background-color: ${props =>
|
||||
props.isSelected ? props.theme.colors.paneCard : props.theme.colors.paneBG}
|
||||
:hover {
|
||||
background-color: ${props => props.theme.colors.paneCard};
|
||||
}
|
||||
`;
|
||||
|
||||
const HTTPMethod = styled.span<{ method: string }>`
|
||||
flex: 1;
|
||||
color: ${props => {
|
||||
switch (props.method) {
|
||||
case "GET":
|
||||
return "#29CCA3";
|
||||
case "POST":
|
||||
return "#F7C75B";
|
||||
case "PUT":
|
||||
return "#30A5E0";
|
||||
case "DELETE":
|
||||
return "#CE4257";
|
||||
default:
|
||||
return "#333";
|
||||
}
|
||||
}};
|
||||
`;
|
||||
|
||||
const ActionName = styled.span`
|
||||
flex: 3;
|
||||
`;
|
||||
|
||||
interface ReduxStateProps {
|
||||
actions: ActionDataState;
|
||||
}
|
||||
|
||||
interface ReduxActionProps {
|
||||
fetchActions: () => void;
|
||||
selectAction: (id: string) => void;
|
||||
}
|
||||
|
||||
type Props = ReduxStateProps &
|
||||
ReduxActionProps &
|
||||
RouteComponentProps<{ id: string }>;
|
||||
|
||||
class ApiSidebar extends React.Component<Props> {
|
||||
componentDidMount(): void {
|
||||
this.props.fetchActions();
|
||||
}
|
||||
|
||||
class ApiSidebar extends React.Component {
|
||||
render() {
|
||||
return <p>Apis</p>;
|
||||
const { actions, history, match } = this.props;
|
||||
const activeActionId = match.params.id;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{actions.loading && "Loading..."}
|
||||
{actions.data.map(action => (
|
||||
<ApiItem
|
||||
key={action.id}
|
||||
onClick={() => history.push(API_EDITOR_ID_URL(action.id))}
|
||||
isSelected={activeActionId === action.id}
|
||||
>
|
||||
<HTTPMethod method={action.actionConfiguration.httpMethod}>
|
||||
{action.actionConfiguration.httpMethod}
|
||||
</HTTPMethod>
|
||||
<ActionName>{action.name}</ActionName>
|
||||
</ApiItem>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ApiSidebar;
|
||||
const mapStateToProps = (state: AppState): ReduxStateProps => ({
|
||||
actions: state.entities.actions,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: any) => ({
|
||||
fetchActions: () => dispatch(fetchActions()),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(ApiSidebar);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import styled from "styled-components";
|
|||
import { AppState } from "../../reducers";
|
||||
import EditorHeader from "./EditorHeader";
|
||||
import EditorsRouter from "./routes";
|
||||
import NavBar from "../../editorComponents/NavBar";
|
||||
import NavBar from "../../components/editor/NavBar";
|
||||
import WidgetsEditor from "./WidgetsEditor";
|
||||
|
||||
const MainContainer = styled.div`
|
||||
|
|
|
|||
|
|
@ -6,9 +6,14 @@ import {
|
|||
RouteComponentProps,
|
||||
} from "react-router-dom";
|
||||
import ApiEditor from "./ApiEditor";
|
||||
import { API_EDITOR_URL, BUILDER_URL } from "../../constants/routes";
|
||||
import {
|
||||
API_EDITOR_ID_URL,
|
||||
API_EDITOR_URL,
|
||||
BUILDER_URL,
|
||||
} from "../../constants/routes";
|
||||
import { Drawer, Position } from "@blueprintjs/core";
|
||||
import styled from "styled-components";
|
||||
import { theme } from "../../constants/DefaultTheme";
|
||||
|
||||
const MainWrapper = styled.div`
|
||||
position: absolute;
|
||||
|
|
@ -44,10 +49,12 @@ class EditorsRouter extends React.Component<RouteComponentProps, RouterState> {
|
|||
isOpen={drawerOpen}
|
||||
position={Position.LEFT}
|
||||
usePortal={false}
|
||||
size="75%"
|
||||
size={theme.drawerWidth}
|
||||
canOutsideClickClose={true}
|
||||
>
|
||||
<Switch>
|
||||
<Route exact path={API_EDITOR_URL} component={ApiEditor} />
|
||||
<Route exact path={API_EDITOR_ID_URL()} component={ApiEditor} />
|
||||
</Switch>
|
||||
</Drawer>
|
||||
</MainWrapper>
|
||||
|
|
|
|||
|
|
@ -2,15 +2,34 @@ import { createReducer } from "../../utils/AppsmithUtils";
|
|||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxAction,
|
||||
ReduxActionErrorTypes,
|
||||
} from "../../constants/ReduxActionConstants";
|
||||
import _ from "lodash";
|
||||
import { ActionCreateUpdateResponse } from "../../api/ActionAPI";
|
||||
import { PageAction } from "../../constants/ActionConstants";
|
||||
import { RestAction } from "../../api/ActionAPI";
|
||||
|
||||
const initialState: ActionDataState = {};
|
||||
const initialState: ActionDataState = {
|
||||
list: {},
|
||||
data: [],
|
||||
response: {
|
||||
body: null,
|
||||
headers: null,
|
||||
statusCode: "",
|
||||
},
|
||||
loading: false,
|
||||
};
|
||||
|
||||
export interface ActionDataState {
|
||||
[name: string]: ActionCreateUpdateResponse;
|
||||
list: {
|
||||
[name: string]: PageAction;
|
||||
};
|
||||
data: RestAction[];
|
||||
response: {
|
||||
body: any;
|
||||
headers: any;
|
||||
statusCode: string;
|
||||
};
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const actionsReducer = createReducer(initialState, {
|
||||
|
|
@ -19,9 +38,27 @@ const actionsReducer = createReducer(initialState, {
|
|||
action: ReduxAction<PageAction[]>,
|
||||
) => {
|
||||
const actionMap = _.mapKeys(action.payload, (action: PageAction) => {
|
||||
return action.actionId;
|
||||
return action.id;
|
||||
});
|
||||
return { ...state, ...actionMap };
|
||||
return { ...state, list: { ...actionMap } };
|
||||
},
|
||||
[ReduxActionTypes.FETCH_ACTIONS_INIT]: (state: ActionDataState) => {
|
||||
return { ...state, loading: true };
|
||||
},
|
||||
[ReduxActionTypes.FETCH_ACTIONS_SUCCESS]: (
|
||||
state: ActionDataState,
|
||||
action: ReduxAction<RestAction[]>,
|
||||
) => {
|
||||
return { ...state, data: action.payload, loading: false };
|
||||
},
|
||||
[ReduxActionErrorTypes.FETCH_ACTIONS_ERROR]: (state: ActionDataState) => {
|
||||
return { ...state, data: [], loading: false };
|
||||
},
|
||||
[ReduxActionTypes.RUN_ACTION_SUCCESS]: (
|
||||
state: ActionDataState,
|
||||
action: ReduxAction<any>,
|
||||
) => {
|
||||
return { ...state, response: action.payload };
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { combineReducers } from "redux";
|
||||
import entityReducer from "./entityReducers";
|
||||
import uiReducer from "./uiReducers";
|
||||
import { reducer as formReducer } from "redux-form";
|
||||
import { CanvasWidgetsReduxState } from "./entityReducers/canvasWidgetsReducer";
|
||||
import { EditorReduxState } from "./uiReducers/editorReducer";
|
||||
import { ErrorReduxState } from "./uiReducers/errorReducer";
|
||||
|
|
@ -15,6 +16,7 @@ import { WidgetSidebarReduxState } from "./uiReducers/widgetSidebarReducer";
|
|||
const appReducer = combineReducers({
|
||||
entities: entityReducer,
|
||||
ui: uiReducer,
|
||||
form: formReducer,
|
||||
});
|
||||
|
||||
export default appReducer;
|
||||
|
|
|
|||
175
app/client/src/sagas/ActionSagas.ts
Normal file
175
app/client/src/sagas/ActionSagas.ts
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
import {
|
||||
ReduxAction,
|
||||
ReduxActionErrorTypes,
|
||||
ReduxActionTypes,
|
||||
} from "../constants/ReduxActionConstants";
|
||||
import { Intent } from "@blueprintjs/core";
|
||||
import { all, call, select, put, takeEvery } from "redux-saga/effects";
|
||||
import { initialize } from "redux-form";
|
||||
import { ActionPayload, PageAction } from "../constants/ActionConstants";
|
||||
import ActionAPI, {
|
||||
ActionCreateUpdateResponse,
|
||||
ExecuteActionRequest,
|
||||
RestAction,
|
||||
} from "../api/ActionAPI";
|
||||
import { AppState } from "../reducers";
|
||||
import { JSONPath } from "jsonpath-plus";
|
||||
import _ from "lodash";
|
||||
import { mapToPropList } from "../utils/AppsmithUtils";
|
||||
import AppToaster from "../components/editor/ToastComponent";
|
||||
import { GenericApiResponse } from "../api/ApiResponses";
|
||||
import { fetchActions } from "../actions/actionActions";
|
||||
|
||||
const getDataTree = (state: AppState) => {
|
||||
return state.entities;
|
||||
};
|
||||
|
||||
const getAction = (state: AppState, actionId: string): PageAction => {
|
||||
return state.entities.actions.list[actionId];
|
||||
};
|
||||
|
||||
export function* evaluateJSONPathSaga(jsonPath: string): any {
|
||||
const dataTree = yield select(getDataTree);
|
||||
return JSONPath({ path: jsonPath, json: dataTree });
|
||||
}
|
||||
|
||||
export function* executeAPIQueryActionSaga(apiAction: ActionPayload) {
|
||||
const api: PageAction = yield select(getAction, apiAction.actionId);
|
||||
|
||||
const executeActionRequest: ExecuteActionRequest = {
|
||||
actionId: apiAction.actionId,
|
||||
};
|
||||
if (!_.isNil(api.jsonPathKeys)) {
|
||||
const responses: any = yield all(
|
||||
api.jsonPathKeys.map((jsonPath: string) => {
|
||||
return call(evaluateJSONPathSaga, jsonPath);
|
||||
}),
|
||||
);
|
||||
const dynamicBindingMap: Record<string, any> = _.keyBy(
|
||||
responses,
|
||||
(response: string, index: number) => {
|
||||
return api.jsonPathKeys ? api.jsonPathKeys[index] : undefined;
|
||||
},
|
||||
);
|
||||
executeActionRequest.dynamicBindingList = mapToPropList(dynamicBindingMap);
|
||||
}
|
||||
yield ActionAPI.executeAction(executeActionRequest);
|
||||
}
|
||||
|
||||
export function* executeActionSaga(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;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function* createActionSaga(actionPayload: ReduxAction<RestAction>) {
|
||||
const response: ActionCreateUpdateResponse = yield ActionAPI.createAPI(
|
||||
actionPayload.payload,
|
||||
);
|
||||
if (response.responseMeta.success) {
|
||||
AppToaster.show({
|
||||
message: `${actionPayload.payload.name} Action created`,
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
yield put(fetchActions());
|
||||
}
|
||||
}
|
||||
|
||||
export function* fetchActionsSaga() {
|
||||
const response: GenericApiResponse<
|
||||
RestAction[]
|
||||
> = yield ActionAPI.fetchActions();
|
||||
if (response.responseMeta.success) {
|
||||
yield put({
|
||||
type: ReduxActionTypes.FETCH_ACTIONS_SUCCESS,
|
||||
payload: response.data,
|
||||
});
|
||||
} else {
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.FETCH_ACTIONS_ERROR,
|
||||
payload: response.responseMeta.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function* fetchActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
||||
const response: GenericApiResponse<RestAction> = yield ActionAPI.fetchAPI(
|
||||
actionPayload.payload.id,
|
||||
);
|
||||
const data = response.data;
|
||||
yield put(initialize("ApiEditorForm", data));
|
||||
}
|
||||
|
||||
export function* runActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
||||
const id = actionPayload.payload.id;
|
||||
const response: any = yield ActionAPI.executeAction({ actionId: id });
|
||||
yield put({
|
||||
type: ReduxActionTypes.RUN_ACTION_SUCCESS,
|
||||
payload: response,
|
||||
});
|
||||
}
|
||||
|
||||
export function* updateActionSaga(
|
||||
actionPayload: ReduxAction<{ data: RestAction }>,
|
||||
) {
|
||||
const finalFields: Partial<RestAction> = _.omit(
|
||||
actionPayload.payload.data,
|
||||
"new",
|
||||
);
|
||||
const response: GenericApiResponse<RestAction> = yield ActionAPI.updateAPI(
|
||||
finalFields,
|
||||
);
|
||||
if (response.responseMeta.success) {
|
||||
AppToaster.show({
|
||||
message: `${actionPayload.payload.data.name} Action updated`,
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
yield put(fetchActions());
|
||||
} else {
|
||||
AppToaster.show({
|
||||
message: "Error occurred when updating action",
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function* deleteActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
||||
const id = actionPayload.payload.id;
|
||||
const response: GenericApiResponse<RestAction> = yield ActionAPI.deleteAction(
|
||||
id,
|
||||
);
|
||||
if (response.responseMeta.success) {
|
||||
AppToaster.show({
|
||||
message: `${response.data.name} Action deleted`,
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
yield put(fetchActions());
|
||||
} else {
|
||||
AppToaster.show({
|
||||
message: "Error occurred when deleting action",
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function* watchActionSagas() {
|
||||
yield all([
|
||||
takeEvery(ReduxActionTypes.FETCH_ACTIONS_INIT, fetchActionsSaga),
|
||||
takeEvery(ReduxActionTypes.EXECUTE_ACTION, executeActionSaga),
|
||||
takeEvery(ReduxActionTypes.CREATE_ACTION, createActionSaga),
|
||||
takeEvery(ReduxActionTypes.FETCH_ACTION, fetchActionSaga),
|
||||
takeEvery(ReduxActionTypes.RUN_ACTION, runActionSaga),
|
||||
takeEvery(ReduxActionTypes.UPDATE_ACTION, updateActionSaga),
|
||||
takeEvery(ReduxActionTypes.DELETE_ACTION, deleteActionSaga),
|
||||
]);
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxAction,
|
||||
} from "../constants/ReduxActionConstants";
|
||||
import { call, takeEvery, select, all } from "redux-saga/effects";
|
||||
import { PageAction, ActionPayload } from "../constants/ActionConstants";
|
||||
import ActionAPI, {
|
||||
ActionCreateUpdateResponse,
|
||||
ExecuteActionRequest,
|
||||
} from "../api/ActionAPI";
|
||||
import { AppState } from "../reducers";
|
||||
import { JSONPath } from "jsonpath-plus";
|
||||
import _ from "lodash";
|
||||
import { mapToPropList } from "../utils/AppsmithUtils";
|
||||
|
||||
const getDataTree = (state: AppState) => {
|
||||
return state.entities;
|
||||
};
|
||||
|
||||
const getAction = (
|
||||
state: AppState,
|
||||
actionId: string,
|
||||
): ActionCreateUpdateResponse => {
|
||||
return state.entities.actions[actionId];
|
||||
};
|
||||
|
||||
export function* evaluateJSONPathSaga(jsonPath: string): any {
|
||||
const dataTree = yield select(getDataTree);
|
||||
const result = JSONPath({ path: jsonPath, json: dataTree });
|
||||
return result;
|
||||
}
|
||||
|
||||
export function* executeAPIQueryActionSaga(apiAction: ActionPayload) {
|
||||
const api: PageAction = yield select(getAction, apiAction.actionId);
|
||||
|
||||
const executeActionRequest: ExecuteActionRequest = {
|
||||
actionId: apiAction.actionId,
|
||||
};
|
||||
if (!_.isNil(api.dynamicBindings)) {
|
||||
const responses: any = yield all(
|
||||
api.dynamicBindings.map((jsonPath: string) => {
|
||||
return call(evaluateJSONPathSaga, jsonPath);
|
||||
}),
|
||||
);
|
||||
const dynamicBindingMap: Record<string, any> = _.keyBy(
|
||||
responses,
|
||||
(response: string, index: number) => {
|
||||
return api.dynamicBindings ? api.dynamicBindings[index] : undefined;
|
||||
},
|
||||
);
|
||||
executeActionRequest.dynamicBindingList = mapToPropList(dynamicBindingMap);
|
||||
}
|
||||
yield ActionAPI.executeAction(executeActionRequest);
|
||||
}
|
||||
|
||||
export function* executeActionSaga(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;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function* watchExecuteActionSaga() {
|
||||
yield takeEvery(ReduxActionTypes.EXECUTE_ACTION, executeActionSaga);
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import {
|
|||
ReduxActionErrorTypes,
|
||||
ReduxAction,
|
||||
} from "../constants/ReduxActionConstants";
|
||||
import AppToaster from "../editorComponents/ToastComponent";
|
||||
import AppToaster from "../components/editor/ToastComponent";
|
||||
import {
|
||||
DEFAULT_ERROR_MESSAGE,
|
||||
DEFAULT_ACTION_ERROR,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { all, spawn } from "redux-saga/effects";
|
||||
import pageSagas from "../sagas/PageSagas";
|
||||
import { fetchWidgetCardsSaga } from "./WidgetSidebarSagas";
|
||||
import { watchExecuteActionSaga } from "./ActionSagas";
|
||||
import { watchActionSagas } from "./ActionSagas";
|
||||
import widgetOperationSagas from "./WidgetOperationSagas";
|
||||
import errorSagas from "./ErrorSagas";
|
||||
import configsSagas from "./ConfigsSagas";
|
||||
|
|
@ -9,7 +9,7 @@ export function* rootSaga() {
|
|||
yield all([
|
||||
spawn(pageSagas),
|
||||
spawn(fetchWidgetCardsSaga),
|
||||
spawn(watchExecuteActionSaga),
|
||||
spawn(watchActionSagas),
|
||||
spawn(widgetOperationSagas),
|
||||
spawn(errorSagas),
|
||||
spawn(configsSagas),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import * as React from "react";
|
||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||
import { WidgetType } from "../constants/WidgetConstants";
|
||||
import ButtonComponent from "../editorComponents/ButtonComponent";
|
||||
import ButtonComponent from "../components/canvas/Button";
|
||||
import { ActionPayload } from "../constants/ActionConstants";
|
||||
|
||||
class ButtonWidget extends BaseWidget<ButtonWidgetProps, WidgetState> {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import React from "react";
|
||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||
import { WidgetType } from "../constants/WidgetConstants";
|
||||
import TextComponent from "../editorComponents/TextComponent";
|
||||
import TextViewComponent from "../components/canvas/TextViewComponent";
|
||||
|
||||
class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
|
||||
getPageView() {
|
||||
return (
|
||||
<TextComponent
|
||||
<TextViewComponent
|
||||
style={this.getPositionStyle()}
|
||||
widgetId={this.props.widgetId}
|
||||
key={this.props.widgetId}
|
||||
|
|
|
|||
|
|
@ -861,6 +861,13 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.2.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5":
|
||||
version "7.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f"
|
||||
integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6"
|
||||
|
|
@ -965,6 +972,42 @@
|
|||
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-9.0.1.tgz#c27b391d8457d1e893f1eddeaf5e5412d12ffbb5"
|
||||
integrity sha512-6It2EVfGskxZCQhuykrfnALg7oVeiI6KclWSmGDqB0AiInVrTGB9Jp9i4/Ad21u9Jde/voVQz6eFX/eSg/UsPA==
|
||||
|
||||
"@emotion/cache@^10.0.17", "@emotion/cache@^10.0.9":
|
||||
version "10.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.19.tgz#d258d94d9c707dcadaf1558def968b86bb87ad71"
|
||||
integrity sha512-BoiLlk4vEsGBg2dAqGSJu0vJl/PgVtCYLBFJaEO8RmQzPugXewQCXZJNXTDFaRlfCs0W+quesayav4fvaif5WQ==
|
||||
dependencies:
|
||||
"@emotion/sheet" "0.9.3"
|
||||
"@emotion/stylis" "0.8.4"
|
||||
"@emotion/utils" "0.11.2"
|
||||
"@emotion/weak-memoize" "0.2.4"
|
||||
|
||||
"@emotion/core@^10.0.9":
|
||||
version "10.0.21"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.21.tgz#2e8398d2b92fd90d4ed6ac4d0b66214971de3458"
|
||||
integrity sha512-U9zbc7ovZ2ceIwbLXYZPJy6wPgnOdTNT4jENZ31ee6v2lojetV5bTbCVk6ciT8G3wQRyVaTTfUCH9WCrMzpRIw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
"@emotion/cache" "^10.0.17"
|
||||
"@emotion/css" "^10.0.14"
|
||||
"@emotion/serialize" "^0.11.10"
|
||||
"@emotion/sheet" "0.9.3"
|
||||
"@emotion/utils" "0.11.2"
|
||||
|
||||
"@emotion/css@^10.0.14", "@emotion/css@^10.0.9":
|
||||
version "10.0.14"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.14.tgz#95dacabdd0e22845d1a1b0b5968d9afa34011139"
|
||||
integrity sha512-MozgPkBEWvorcdpqHZE5x1D/PLEHUitALQCQYt2wayf4UNhpgQs2tN0UwHYS4FMy5ROBH+0ALyCFVYJ/ywmwlg==
|
||||
dependencies:
|
||||
"@emotion/serialize" "^0.11.8"
|
||||
"@emotion/utils" "0.11.2"
|
||||
babel-plugin-emotion "^10.0.14"
|
||||
|
||||
"@emotion/hash@0.7.3":
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.3.tgz#a166882c81c0c6040975dd30df24fae8549bd96f"
|
||||
integrity sha512-14ZVlsB9akwvydAdaEnVnvqu6J2P6ySv39hYyl/aoB6w/V+bXX0tay8cF6paqbgZsN2n5Xh15uF4pE+GvE+itw==
|
||||
|
||||
"@emotion/is-prop-valid@^0.8.1":
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.2.tgz#b9692080da79041683021fcc32f96b40c54c59dc"
|
||||
|
|
@ -977,11 +1020,47 @@
|
|||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.2.tgz#7f4c71b7654068dfcccad29553520f984cc66b30"
|
||||
integrity sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w==
|
||||
|
||||
"@emotion/unitless@^0.7.0":
|
||||
"@emotion/memoize@0.7.3":
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78"
|
||||
integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==
|
||||
|
||||
"@emotion/serialize@^0.11.10", "@emotion/serialize@^0.11.11", "@emotion/serialize@^0.11.8":
|
||||
version "0.11.11"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.11.tgz#c92a5e5b358070a7242d10508143306524e842a4"
|
||||
integrity sha512-YG8wdCqoWtuoMxhHZCTA+egL0RSGdHEc+YCsmiSBPBEDNuVeMWtjEWtGrhUterSChxzwnWBXvzSxIFQI/3sHLw==
|
||||
dependencies:
|
||||
"@emotion/hash" "0.7.3"
|
||||
"@emotion/memoize" "0.7.3"
|
||||
"@emotion/unitless" "0.7.4"
|
||||
"@emotion/utils" "0.11.2"
|
||||
csstype "^2.5.7"
|
||||
|
||||
"@emotion/sheet@0.9.3":
|
||||
version "0.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.3.tgz#689f135ecf87d3c650ed0c4f5ddcbe579883564a"
|
||||
integrity sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A==
|
||||
|
||||
"@emotion/stylis@0.8.4":
|
||||
version "0.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.4.tgz#6c51afdf1dd0d73666ba09d2eb6c25c220d6fe4c"
|
||||
integrity sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ==
|
||||
|
||||
"@emotion/unitless@0.7.4", "@emotion/unitless@^0.7.0":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.4.tgz#a87b4b04e5ae14a88d48ebef15015f6b7d1f5677"
|
||||
integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ==
|
||||
|
||||
"@emotion/utils@0.11.2":
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.2.tgz#713056bfdffb396b0a14f1c8f18e7b4d0d200183"
|
||||
integrity sha512-UHX2XklLl3sIaP6oiMmlVzT0J+2ATTVpf0dHQVyPJHTkOITvXfaSqnRk6mdDhV9pR8T/tHc3cex78IKXssmzrA==
|
||||
|
||||
"@emotion/weak-memoize@0.2.4":
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.4.tgz#622a72bebd1e3f48d921563b4b60a762295a81fc"
|
||||
integrity sha512-6PYY5DVdAY1ifaQW6XYTnOMihmBVT27elqSjEoodchsGjzYlEsTQMcEhSud99kVawatyTZRTiVkJ/c6lwbQ7nA==
|
||||
|
||||
"@hapi/address@2.x.x":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.1.tgz#61395b5ed94c4cb19c2dc4c85969cff3d40d583f"
|
||||
|
|
@ -1590,6 +1669,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
|
||||
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
|
||||
|
||||
"@types/react-dom@*":
|
||||
version "16.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.2.tgz#90f9e6c161850be1feb31d2f448121be2a4f3b47"
|
||||
integrity sha512-hgPbBoI1aTSTvZwo8HYw35UaTldW6n2ETLvHAcfcg1FaOuBV3olmyCe5eMpx2WybWMBPv0MdU2t5GOcQhP+3zA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@^16.8.0":
|
||||
version "16.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.0.tgz#ba6ddb00bf5de700b0eb91daa452081ffccbfdea"
|
||||
|
|
@ -1632,6 +1718,29 @@
|
|||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-select@^3.0.5":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-3.0.5.tgz#c615c1f7a0ea98e828b469d0f5ddd39ba3f0d319"
|
||||
integrity sha512-BodHwzj9WU1EWC1j8zx1iyAMDCrTURwdvMpOVvVFwDVU7fvs8Ks9fPTkUY3+BgYbpOJFr21bR3Jib/GonwanAQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
"@types/react-dom" "*"
|
||||
"@types/react-transition-group" "*"
|
||||
|
||||
"@types/react-tabs@^2.3.1":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-tabs/-/react-tabs-2.3.1.tgz#62d3322667ac228c4d0f9f36ac9f86988c0b3971"
|
||||
integrity sha512-4SZXSF8ibQAtHUqqfoYLO+8Rn4F7Hj/IX3CJf1712dWeFvRxYY1HjjwSoN4MgUB0SB0dY4GrdlZwNhhIKuRoNQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@*":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.2.3.tgz#4924133f7268694058e415bf7aea2d4c21131470"
|
||||
integrity sha512-Hk8jiuT7iLOHrcjKP/ZVSyCNXK73wJAUz60xm0mVhiRujrdiI++j4duLiL282VGxwAgxetHQFfqA29LgEeSkFA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^16.8.2":
|
||||
version "16.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.2.tgz#6d1765431a1ad1877979013906731aae373de268"
|
||||
|
|
@ -1640,6 +1749,14 @@
|
|||
"@types/prop-types" "*"
|
||||
csstype "^2.2.0"
|
||||
|
||||
"@types/redux-form@^8.1.9":
|
||||
version "8.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/redux-form/-/redux-form-8.1.9.tgz#8e8800541ce191f7145b8ddf3d926ed5dfeb42d3"
|
||||
integrity sha512-JdXoybK8gL4TDFzHASiUpK7YaoQ1HqBZzXkHEUUGlOR0t2i2y42EXEyWuRtMKm/8NdoO9kPANd+mFGgJ07HIFA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
redux "^3.6.0 || ^4.0.0"
|
||||
|
||||
"@types/resolve@0.0.8":
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
|
||||
|
|
@ -1930,6 +2047,11 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
|
|||
mime-types "~2.1.24"
|
||||
negotiator "0.6.2"
|
||||
|
||||
ace-builds@^1.4.6:
|
||||
version "1.4.7"
|
||||
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.7.tgz#56e5465270b6c48a48d30e70d6b8f6b92fbf2b08"
|
||||
integrity sha512-gwQGVFewBopRLho08BfahyvRa9FlB43JUig5ItAKTYc9kJJsbA9QNz75p28QtQomoPQ9rJx82ymL21x4ZSZmdg==
|
||||
|
||||
acorn-globals@^4.1.0, acorn-globals@^4.3.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
|
||||
|
|
@ -2195,7 +2317,7 @@ arrify@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
||||
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
|
||||
|
||||
asap@^2.0.6, asap@~2.0.6:
|
||||
asap@^2.0.6, asap@~2.0.3, asap@~2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
|
||||
|
|
@ -2400,6 +2522,22 @@ babel-plugin-dynamic-import-node@2.3.0, babel-plugin-dynamic-import-node@^2.3.0:
|
|||
dependencies:
|
||||
object.assign "^4.1.0"
|
||||
|
||||
babel-plugin-emotion@^10.0.14:
|
||||
version "10.0.21"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.21.tgz#9ebeb12edeea3e60a5476b0e07c9868605e65968"
|
||||
integrity sha512-03o+T6sfVAJhNDcSdLapgv4IeewcFPzxlvBUVdSf7o5PI57ZSxoDvmy+ZulVWSu+rOWAWkEejNcsb29TuzJHbg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@emotion/hash" "0.7.3"
|
||||
"@emotion/memoize" "0.7.3"
|
||||
"@emotion/serialize" "^0.11.11"
|
||||
babel-plugin-macros "^2.0.0"
|
||||
babel-plugin-syntax-jsx "^6.18.0"
|
||||
convert-source-map "^1.5.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
find-root "^1.1.0"
|
||||
source-map "^0.5.7"
|
||||
|
||||
babel-plugin-istanbul@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854"
|
||||
|
|
@ -2417,7 +2555,7 @@ babel-plugin-jest-hoist@^24.9.0:
|
|||
dependencies:
|
||||
"@types/babel__traverse" "^7.0.6"
|
||||
|
||||
babel-plugin-macros@2.6.1:
|
||||
babel-plugin-macros@2.6.1, babel-plugin-macros@^2.0.0:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.1.tgz#41f7ead616fc36f6a93180e89697f69f51671181"
|
||||
integrity sha512-6W2nwiXme6j1n2erPOnmRiWfObUhWH7Qw1LMi9XZy8cj+KtESu3T6asZvtk5bMQQjX8te35o7CFueiSdL/2NmQ==
|
||||
|
|
@ -2522,6 +2660,11 @@ balanced-match@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
base16@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
|
||||
integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
|
||||
|
|
@ -3017,7 +3160,7 @@ class-utils@^0.3.5:
|
|||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
classnames@^2.2, classnames@^2.2.5:
|
||||
classnames@^2.2, classnames@^2.2.0, classnames@^2.2.5:
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||
|
|
@ -3299,7 +3442,7 @@ content-type@~1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
convert-source-map@1.6.0, convert-source-map@^1.1.0, convert-source-map@^1.4.0:
|
||||
convert-source-map@1.6.0, convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
|
||||
integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
|
||||
|
|
@ -3351,6 +3494,11 @@ core-js@3.1.4:
|
|||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.4.tgz#3a2837fc48e582e1ae25907afcd6cf03b0cc7a07"
|
||||
integrity sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
|
||||
|
||||
core-js@^2.4.0, core-js@^2.6.5:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
|
||||
|
|
@ -3688,6 +3836,11 @@ csstype@^2.2.0:
|
|||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41"
|
||||
integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==
|
||||
|
||||
csstype@^2.5.7:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.7.tgz#20b0024c20b6718f4eda3853a1f5a1cce7f5e4a5"
|
||||
integrity sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==
|
||||
|
||||
currently-unhandled@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
|
||||
|
|
@ -3932,6 +4085,11 @@ detect-port-alt@1.1.6:
|
|||
address "^1.0.1"
|
||||
debug "^2.6.0"
|
||||
|
||||
diff-match-patch@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.4.tgz#6ac4b55237463761c4daf0dc603eb869124744b1"
|
||||
integrity sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg==
|
||||
|
||||
diff-sequences@^24.9.0:
|
||||
version "24.9.0"
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
|
||||
|
|
@ -4190,6 +4348,13 @@ encodeurl@~1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
|
||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
|
||||
|
|
@ -4271,6 +4436,11 @@ es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@^0.10.51:
|
|||
es6-symbol "~3.1.1"
|
||||
next-tick "^1.0.0"
|
||||
|
||||
es6-error@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
||||
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
||||
|
||||
es6-iterator@2.0.3, es6-iterator@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
||||
|
|
@ -4808,6 +4978,26 @@ fb-watchman@^2.0.0:
|
|||
dependencies:
|
||||
bser "^2.0.0"
|
||||
|
||||
fbemitter@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865"
|
||||
integrity sha1-Uj4U/a9SSIBbsC9i78M75wP1GGU=
|
||||
dependencies:
|
||||
fbjs "^0.8.4"
|
||||
|
||||
fbjs@^0.8.0, fbjs@^0.8.4:
|
||||
version "0.8.17"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
|
||||
integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.18"
|
||||
|
||||
figgy-pudding@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
||||
|
|
@ -4896,6 +5086,11 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
|
|||
make-dir "^2.0.0"
|
||||
pkg-dir "^3.0.0"
|
||||
|
||||
find-root@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
|
||||
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
|
||||
|
||||
find-up@3.0.0, find-up@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
|
||||
|
|
@ -4958,6 +5153,14 @@ flush-write-stream@^1.0.0:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
flux@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/flux/-/flux-3.1.3.tgz#d23bed515a79a22d933ab53ab4ada19d05b2f08a"
|
||||
integrity sha1-0jvtUVp5oi2TOrU6tK2hnQWy8Io=
|
||||
dependencies:
|
||||
fbemitter "^2.0.0"
|
||||
fbjs "^0.8.0"
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
|
|
@ -5487,7 +5690,7 @@ hmac-drbg@^1.0.0:
|
|||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
|
||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.2.1, hoist-non-react-statics@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
|
||||
integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==
|
||||
|
|
@ -5670,7 +5873,7 @@ husky@^3.0.5:
|
|||
run-node "^1.0.0"
|
||||
slash "^3.0.0"
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
|
|
@ -5733,6 +5936,11 @@ immer@1.10.0:
|
|||
resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
|
||||
integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==
|
||||
|
||||
immutable@3.8.2:
|
||||
version "3.8.2"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
|
||||
integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=
|
||||
|
||||
import-cwd@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
|
||||
|
|
@ -6185,7 +6393,7 @@ is-root@2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c"
|
||||
integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==
|
||||
|
||||
is-stream@^1.1.0:
|
||||
is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
|
@ -6261,6 +6469,14 @@ isobject@^3.0.0, isobject@^3.0.1:
|
|||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
|
|
@ -7146,11 +7362,36 @@ locate-path@^5.0.0:
|
|||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
lodash-es@^4.17.15:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
|
||||
integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
|
||||
|
||||
lodash._reinterpolate@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
|
||||
|
||||
lodash.curry@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
|
||||
integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA=
|
||||
|
||||
lodash.flow@^3.3.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
|
||||
integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
|
||||
lodash.memoize@4.x, lodash.memoize@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
|
|
@ -7729,6 +7970,14 @@ no-case@^2.2.0:
|
|||
dependencies:
|
||||
lower-case "^1.1.1"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
node-forge@0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.8.2.tgz#b4bcc59fb12ce77a8825fc6a783dfe3182499c5a"
|
||||
|
|
@ -9362,6 +9611,13 @@ promise@8.0.3:
|
|||
dependencies:
|
||||
asap "~2.0.6"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prompts@^2.0.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35"
|
||||
|
|
@ -9370,7 +9626,7 @@ prompts@^2.0.1:
|
|||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.3"
|
||||
|
||||
prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.0, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
|
|
@ -9454,6 +9710,11 @@ punycode@^2.1.0, punycode@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
pure-color@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e"
|
||||
integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=
|
||||
|
||||
q@^1.1.2:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
|
|
@ -9543,6 +9804,17 @@ re-resizable@6.1.0:
|
|||
dependencies:
|
||||
fast-memoize "^2.5.1"
|
||||
|
||||
react-ace@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-8.0.0.tgz#e6fc155ec3cf240e92bdf2e156a50458a78ed0a4"
|
||||
integrity sha512-EvU14vXbZpAenb1ZVKdn8yTQs/shZ9RghFulHtt67bBXT6sjrNHcfOEXHYtSEmwMb6pQVVNNuulzzd8o+Uouig==
|
||||
dependencies:
|
||||
ace-builds "^1.4.6"
|
||||
diff-match-patch "^1.0.4"
|
||||
lodash.get "^4.4.2"
|
||||
lodash.isequal "^4.5.0"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-app-polyfill@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-1.0.2.tgz#2a51175885c88245a2a356dc46df29f38ec9f060"
|
||||
|
|
@ -9555,6 +9827,16 @@ react-app-polyfill@^1.0.2:
|
|||
regenerator-runtime "0.13.3"
|
||||
whatwg-fetch "3.0.0"
|
||||
|
||||
react-base16-styling@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c"
|
||||
integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=
|
||||
dependencies:
|
||||
base16 "^1.0.0"
|
||||
lodash.curry "^4.0.1"
|
||||
lodash.flow "^3.3.0"
|
||||
pure-color "^1.2.0"
|
||||
|
||||
react-day-picker@^7.3.2:
|
||||
version "7.3.2"
|
||||
resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-7.3.2.tgz#b9b9b0000ba53b2c9df9bccb79664862aba6b60a"
|
||||
|
|
@ -9643,11 +9925,28 @@ react-error-overlay@^6.0.1:
|
|||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.1.tgz#b8d3cf9bb991c02883225c48044cb3ee20413e0f"
|
||||
integrity sha512-V9yoTr6MeZXPPd4nV/05eCBvGH9cGzc52FN8fs0O0TVQ3HYYf1n7EgZVtHbldRq5xU9zEzoXIITjYNIfxDDdUw==
|
||||
|
||||
react-input-autosize@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2"
|
||||
integrity sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.2, react-is@^16.8.4:
|
||||
version "16.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
|
||||
integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
|
||||
|
||||
react-json-view@^1.19.1:
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c"
|
||||
integrity sha512-u5e0XDLIs9Rj43vWkKvwL8G3JzvXSl6etuS5G42a8klMohZuYFQzSN6ri+/GiBptDqlrXPTdExJVU7x9rrlXhg==
|
||||
dependencies:
|
||||
flux "^3.1.3"
|
||||
react-base16-styling "^0.6.0"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
react-textarea-autosize "^6.1.0"
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
|
|
@ -9784,7 +10083,36 @@ react-scripts@^3.1.1:
|
|||
optionalDependencies:
|
||||
fsevents "2.0.7"
|
||||
|
||||
react-transition-group@^2.9.0:
|
||||
react-select@^3.0.8:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.0.8.tgz#06ff764e29db843bcec439ef13e196865242e0c1"
|
||||
integrity sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.4"
|
||||
"@emotion/cache" "^10.0.9"
|
||||
"@emotion/core" "^10.0.9"
|
||||
"@emotion/css" "^10.0.9"
|
||||
memoize-one "^5.0.0"
|
||||
prop-types "^15.6.0"
|
||||
react-input-autosize "^2.2.2"
|
||||
react-transition-group "^2.2.1"
|
||||
|
||||
react-tabs@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-3.0.0.tgz#60311a17c755eb6aa9b3310123e67db421605127"
|
||||
integrity sha512-z90cDIb+5V7MzjXFHq1VLxYiMH7dDQWan7mXSw6BWQtw+9pYAnq/fEDvsPaXNyevYitvLetdW87C61uu27JVMA==
|
||||
dependencies:
|
||||
classnames "^2.2.0"
|
||||
prop-types "^15.5.0"
|
||||
|
||||
react-textarea-autosize@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz#df91387f8a8f22020b77e3833c09829d706a09a5"
|
||||
integrity sha512-F6bI1dgib6fSvG8so1HuArPUv+iVEfPliuLWusLF+gAKz0FbB4jLrWUrTAeq1afnPT2c9toEZYUdz/y1uKMy4A==
|
||||
dependencies:
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-transition-group@^2.2.1, react-transition-group@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
||||
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
|
||||
|
|
@ -9939,6 +10267,24 @@ redux-devtools@^3.5.0:
|
|||
prop-types "^15.5.7"
|
||||
redux-devtools-instrument "^1.9.0"
|
||||
|
||||
redux-form@^8.2.6:
|
||||
version "8.2.6"
|
||||
resolved "https://registry.yarnpkg.com/redux-form/-/redux-form-8.2.6.tgz#6840bbe9ed5b2aaef9dd82e6db3e5efcfddd69b1"
|
||||
integrity sha512-krmF7wl1C753BYpEpWIVJ5NM4lUJZFZc5GFUVgblT+jprB99VVBDyBcgrZM3gWWLOcncFyNsHcKNQQcFg8Uanw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.2.0"
|
||||
es6-error "^4.1.1"
|
||||
hoist-non-react-statics "^3.2.1"
|
||||
invariant "^2.2.4"
|
||||
is-promise "^2.1.0"
|
||||
lodash "^4.17.15"
|
||||
lodash-es "^4.17.15"
|
||||
prop-types "^15.6.1"
|
||||
react-is "^16.7.0"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
optionalDependencies:
|
||||
immutable "3.8.2"
|
||||
|
||||
redux-saga@^1.0.0:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.0.5.tgz#03317261bc5fa7ee2ecb778f4e4848f573557bbb"
|
||||
|
|
@ -9946,7 +10292,7 @@ redux-saga@^1.0.0:
|
|||
dependencies:
|
||||
"@redux-saga/core" "^1.0.3"
|
||||
|
||||
"redux@>=0.10 <5", redux@^4.0.0, redux@^4.0.1, redux@^4.0.4:
|
||||
"redux@>=0.10 <5", "redux@^3.6.0 || ^4.0.0", redux@^4.0.0, redux@^4.0.1, redux@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796"
|
||||
integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==
|
||||
|
|
@ -10636,7 +10982,7 @@ set-value@^2.0.0, set-value@^2.0.1:
|
|||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
setimmediate@^1.0.4:
|
||||
setimmediate@^1.0.4, setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
|
||||
|
|
@ -10845,7 +11191,7 @@ source-map@^0.4.2:
|
|||
dependencies:
|
||||
amdefine ">=0.0.4"
|
||||
|
||||
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6:
|
||||
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
|
@ -11660,6 +12006,11 @@ typescript@^3.4.5, typescript@^3.6.3:
|
|||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da"
|
||||
integrity sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==
|
||||
|
||||
ua-parser-js@^0.7.18:
|
||||
version "0.7.20"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098"
|
||||
integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==
|
||||
|
||||
uglify-js@3.4.x:
|
||||
version "3.4.10"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
|
||||
|
|
@ -12101,7 +12452,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
|
|||
dependencies:
|
||||
iconv-lite "0.4.24"
|
||||
|
||||
whatwg-fetch@3.0.0:
|
||||
whatwg-fetch@3.0.0, whatwg-fetch@>=0.10.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
|
||||
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user